|
17715
|
777
|
45
|
2026-05-11T10:30:31.384349+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778495431384_m2.jpg...
|
Firefox
|
Screenpipe — Archive — Personal
|
True
|
app.screenpipe.lakylak.xyz
|
monitor_2
|
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
Monitor
Jump to
--
:
--
Go
APP TIMELINE · CLICK TO PLAY · DRAG SCROLLBAR TO PAN
−
1×
+
Follow
Follow
10:00
10:30
11:00
11:30
12:00
12:30
13:00
13:30
14:00
14:30
15:00
15:30
16:00
16:30
17:00
17:30
18:00
18:30
19:00
19:30
20:00
20:30
21:00...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.2942154,"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":"New Tab","depth":5,"bounds":{"left":0.3075133,"top":0.06304868,"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.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":true},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"bounds":{"left":0.3075133,"top":0.09577015,"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.09177973,"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.118914604,"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.29704124,"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.30801198,"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.31914893,"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.3302859,"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.3414229,"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":"Screenpipe [archive.db · 12323.6MB]","depth":7,"bounds":{"left":0.41456118,"top":0.061452515,"width":0.06698803,"height":0.017956903},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Screenpipe","depth":8,"bounds":{"left":0.41456118,"top":0.06304868,"width":0.027759308,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[archive.db · 12323.6MB]","depth":9,"bounds":{"left":0.44365028,"top":0.06703911,"width":0.037898935,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Activity","depth":7,"bounds":{"left":0.48620346,"top":0.059856344,"width":0.024767287,"height":0.0207502},"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,"bounds":{"left":0.51163566,"top":0.059856344,"width":0.023769947,"height":0.0207502},"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,"bounds":{"left":0.53607047,"top":0.059856344,"width":0.020944148,"height":0.0207502},"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,"bounds":{"left":0.55767953,"top":0.059856344,"width":0.03507314,"height":0.0207502},"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,"bounds":{"left":0.5934175,"top":0.059856344,"width":0.029753989,"height":0.0207502},"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,"bounds":{"left":0.62383646,"top":0.059856344,"width":0.034075797,"height":0.0207502},"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,"bounds":{"left":0.93849736,"top":0.0650439,"width":0.008144947,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"07","depth":9,"bounds":{"left":0.9552859,"top":0.06464485,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"bounds":{"left":0.96110374,"top":0.06464485,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"05","depth":9,"bounds":{"left":0.9644282,"top":0.06464485,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"bounds":{"left":0.970246,"top":0.06464485,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026","depth":9,"bounds":{"left":0.9737367,"top":0.06464485,"width":0.009474734,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Calendar","depth":8,"bounds":{"left":0.98454124,"top":0.0650439,"width":0.0051529254,"height":0.010774142},"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":"Monitor","depth":9,"bounds":{"left":0.4945146,"top":0.10853951,"width":0.013464096,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jump to","depth":9,"bounds":{"left":0.8530585,"top":0.10853951,"width":0.01412899,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--","depth":10,"bounds":{"left":0.87317157,"top":0.10814046,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":9,"bounds":{"left":0.87898934,"top":0.10814046,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--","depth":10,"bounds":{"left":0.88231385,"top":0.10814046,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Go","depth":8,"bounds":{"left":0.90109706,"top":0.10454908,"width":0.012300532,"height":0.018754989},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"APP TIMELINE · CLICK TO PLAY · DRAG SCROLLBAR TO PAN","depth":10,"bounds":{"left":0.49950132,"top":0.14964086,"width":0.10571808,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"−","depth":9,"bounds":{"left":0.8558843,"top":0.1452514,"width":0.009807181,"height":0.018754989},"on_screen":true,"help_text":"Zoom out","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1×","depth":10,"bounds":{"left":0.86984706,"top":0.14924182,"width":0.004155585,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"+","depth":9,"bounds":{"left":0.87832445,"top":0.1452514,"width":0.009640957,"height":0.018754989},"on_screen":true,"help_text":"Zoom in","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Follow","depth":10,"bounds":{"left":0.8912899,"top":0.14924182,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Follow","depth":10,"bounds":{"left":0.89727396,"top":0.14924182,"width":0.011136968,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10:00","depth":13,"bounds":{"left":0.50482047,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10:30","depth":13,"bounds":{"left":0.5219415,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:00","depth":13,"bounds":{"left":0.539395,"top":0.21947326,"width":0.0076462766,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:30","depth":13,"bounds":{"left":0.55651593,"top":0.21947326,"width":0.0076462766,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12:00","depth":13,"bounds":{"left":0.5734708,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12:30","depth":13,"bounds":{"left":0.5905917,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13:00","depth":13,"bounds":{"left":0.607879,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13:30","depth":13,"bounds":{"left":0.625,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"14:00","depth":13,"bounds":{"left":0.642121,"top":0.21947326,"width":0.00831117,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"14:30","depth":13,"bounds":{"left":0.65924203,"top":0.21947326,"width":0.00831117,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15:00","depth":13,"bounds":{"left":0.6765292,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15:30","depth":13,"bounds":{"left":0.69365025,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"16:00","depth":13,"bounds":{"left":0.71077126,"top":0.21947326,"width":0.00831117,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"16:30","depth":13,"bounds":{"left":0.7280585,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17:00","depth":13,"bounds":{"left":0.7453458,"top":0.21947326,"width":0.007978723,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17:30","depth":13,"bounds":{"left":0.7624667,"top":0.21947326,"width":0.007978723,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"18:00","depth":13,"bounds":{"left":0.77958775,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"18:30","depth":13,"bounds":{"left":0.79670876,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19:00","depth":13,"bounds":{"left":0.8138298,"top":0.21947326,"width":0.00831117,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19:30","depth":13,"bounds":{"left":0.83111703,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20:00","depth":13,"bounds":{"left":0.8479056,"top":0.21947326,"width":0.008643617,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20:30","depth":13,"bounds":{"left":0.86519283,"top":0.21947326,"width":0.008643617,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21:00","depth":13,"bounds":{"left":0.88248,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8279161281023706700
|
7300516604176880537
|
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
Monitor
Jump to
--
:
--
Go
APP TIMELINE · CLICK TO PLAY · DRAG SCROLLBAR TO PAN
−
1×
+
Follow
Follow
10:00
10:30
11:00
11:30
12:00
12:30
13:00
13:30
14:00
14:30
15:00
15:30
16:00
16:30
17:00
17:30
18:00
18:30
19:00
19:30
20:00
20:30
21:00...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
17805
|
779
|
17
|
2026-05-11T10:34:10.487211+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778495650487_m2.jpg...
|
Firefox
|
Screenpipe — Archive — Personal
|
True
|
app.screenpipe.lakylak.xyz
|
monitor_2
|
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
Monitor
Jump to
--
:
--
Go
APP TIMELINE · CLICK TO PLAY · DRAG SCROLLBAR TO PAN
−
1×
+
Follow
Follow
10:00
10:30
11:00
11:30
12:00
12:30
13:00
13:30
14:00
14:30
15:00
15:30
16:00
16:30
17:00
17:30
18:00
18:30
19:00
19:30
20:00
20:30
21:00...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.2942154,"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":"New Tab","depth":5,"bounds":{"left":0.3075133,"top":0.06304868,"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.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":true},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"bounds":{"left":0.3075133,"top":0.09577015,"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.09177973,"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.118914604,"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.29704124,"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.30801198,"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.31914893,"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.3302859,"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.3414229,"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":"Screenpipe [archive.db · 12323.6MB]","depth":7,"bounds":{"left":0.41456118,"top":0.061452515,"width":0.06698803,"height":0.017956903},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Screenpipe","depth":8,"bounds":{"left":0.41456118,"top":0.06304868,"width":0.027759308,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[archive.db · 12323.6MB]","depth":9,"bounds":{"left":0.44365028,"top":0.06703911,"width":0.037898935,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Activity","depth":7,"bounds":{"left":0.48620346,"top":0.059856344,"width":0.024767287,"height":0.0207502},"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,"bounds":{"left":0.51163566,"top":0.059856344,"width":0.023769947,"height":0.0207502},"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,"bounds":{"left":0.53607047,"top":0.059856344,"width":0.020944148,"height":0.0207502},"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,"bounds":{"left":0.55767953,"top":0.059856344,"width":0.03507314,"height":0.0207502},"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,"bounds":{"left":0.5934175,"top":0.059856344,"width":0.029753989,"height":0.0207502},"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,"bounds":{"left":0.62383646,"top":0.059856344,"width":0.034075797,"height":0.0207502},"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,"bounds":{"left":0.93849736,"top":0.0650439,"width":0.008144947,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"07","depth":9,"bounds":{"left":0.9552859,"top":0.06464485,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"bounds":{"left":0.96110374,"top":0.06464485,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"05","depth":9,"bounds":{"left":0.9644282,"top":0.06464485,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"bounds":{"left":0.970246,"top":0.06464485,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026","depth":9,"bounds":{"left":0.9737367,"top":0.06464485,"width":0.009474734,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Calendar","depth":8,"bounds":{"left":0.98454124,"top":0.0650439,"width":0.0051529254,"height":0.010774142},"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":"Monitor","depth":9,"bounds":{"left":0.4945146,"top":0.10853951,"width":0.013464096,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jump to","depth":9,"bounds":{"left":0.8530585,"top":0.10853951,"width":0.01412899,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--","depth":10,"bounds":{"left":0.87317157,"top":0.10814046,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":9,"bounds":{"left":0.87898934,"top":0.10814046,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--","depth":10,"bounds":{"left":0.88231385,"top":0.10814046,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Go","depth":8,"bounds":{"left":0.90109706,"top":0.10454908,"width":0.012300532,"height":0.018754989},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"APP TIMELINE · CLICK TO PLAY · DRAG SCROLLBAR TO PAN","depth":10,"bounds":{"left":0.49950132,"top":0.14964086,"width":0.10571808,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"−","depth":9,"bounds":{"left":0.8558843,"top":0.1452514,"width":0.009807181,"height":0.018754989},"on_screen":true,"help_text":"Zoom out","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1×","depth":10,"bounds":{"left":0.86984706,"top":0.14924182,"width":0.004155585,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"+","depth":9,"bounds":{"left":0.87832445,"top":0.1452514,"width":0.009640957,"height":0.018754989},"on_screen":true,"help_text":"Zoom in","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Follow","depth":10,"bounds":{"left":0.8912899,"top":0.14924182,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Follow","depth":10,"bounds":{"left":0.89727396,"top":0.14924182,"width":0.011136968,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10:00","depth":13,"bounds":{"left":0.50482047,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10:30","depth":13,"bounds":{"left":0.5219415,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:00","depth":13,"bounds":{"left":0.539395,"top":0.21947326,"width":0.0076462766,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:30","depth":13,"bounds":{"left":0.55651593,"top":0.21947326,"width":0.0076462766,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12:00","depth":13,"bounds":{"left":0.5734708,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12:30","depth":13,"bounds":{"left":0.5905917,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13:00","depth":13,"bounds":{"left":0.607879,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13:30","depth":13,"bounds":{"left":0.625,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"14:00","depth":13,"bounds":{"left":0.642121,"top":0.21947326,"width":0.00831117,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"14:30","depth":13,"bounds":{"left":0.65924203,"top":0.21947326,"width":0.00831117,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15:00","depth":13,"bounds":{"left":0.6765292,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15:30","depth":13,"bounds":{"left":0.69365025,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"16:00","depth":13,"bounds":{"left":0.71077126,"top":0.21947326,"width":0.00831117,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"16:30","depth":13,"bounds":{"left":0.7280585,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17:00","depth":13,"bounds":{"left":0.7453458,"top":0.21947326,"width":0.007978723,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17:30","depth":13,"bounds":{"left":0.7624667,"top":0.21947326,"width":0.007978723,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"18:00","depth":13,"bounds":{"left":0.77958775,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"18:30","depth":13,"bounds":{"left":0.79670876,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19:00","depth":13,"bounds":{"left":0.8138298,"top":0.21947326,"width":0.00831117,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19:30","depth":13,"bounds":{"left":0.83111703,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20:00","depth":13,"bounds":{"left":0.8479056,"top":0.21947326,"width":0.008643617,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20:30","depth":13,"bounds":{"left":0.86519283,"top":0.21947326,"width":0.008643617,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21:00","depth":13,"bounds":{"left":0.88248,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8279161281023706700
|
7300516604176880537
|
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
Monitor
Jump to
--
:
--
Go
APP TIMELINE · CLICK TO PLAY · DRAG SCROLLBAR TO PAN
−
1×
+
Follow
Follow
10:00
10:30
11:00
11:30
12:00
12:30
13:00
13:30
14:00
14:30
15:00
15:30
16:00
16:30
17:00
17:30
18:00
18:30
19:00
19:30
20:00
20:30
21:00...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
12309
|
546
|
18
|
2026-05-09T08:46:15.615181+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778316375615_m2.jpg...
|
Firefox
|
How could Trump be profiting off of the war in Ira How could Trump be profiting off of the war in Iran, since he profits from almost everything he does? - kovaliklukas@gmail.com - Gmail — Personal...
|
True
|
mail.google.com/mail/u/0/#inbox/FMfcgzQgLjQhDDMfdz mail.google.com/mail/u/0/#inbox/FMfcgzQgLjQhDDMfdzjdnHSzRcdplwhT...
|
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
How could Trump be profiting off of the war in Iran, since he profits from almost everything he does? - [EMAIL] - Gmail
How could Trump be profiting off of the war in Iran, since he profits from almost everything he does? - [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 35 unread
Inbox
35
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 8797 unread has menu
Updates
8,797
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
40
of
21,245
Newer
Older
Input tools on/off (Ctrl-Shift-K)
Select input tool
Print all
In new window
How could Trump be profiting off of the war in Iran, since he profits from almost everything he does?
How could Trump be profiting off of the war in Iran, since he profits from almost everything he does?
Not important
Search for all messages with label Inbox
Remove label Inbox from this conversation
Quora Suggested Spaces [EMAIL] Unsubscribe
Quora Suggested Spaces [EMAIL]
Quora Suggested Spaces
[EMAIL]
Unsubscribe
Unsubscribe
Mon 4 May, 08:32 (5 days ago)
Mon 4 May, 08:32 (5 days ago)
Not starred
You can't react to a group with an emoji
Reply
More message options
to
me
Show details
No More Trump No More Trump • 107.4K followers Sustained resistance to the Traitorous Mister Trump, his clones, and his MAGATS.
How could Trump be profiting off of the war in Iran, since he profits from almost everything he does?
How could Trump be profiting off of the war in Iran, since he profits from almost everything he does?
John Mooney
John Mooney
, former USN, Retired at Aviation Ordnaceman (1967-1984)
Answered April 25
Play with this: We get NONE of our oil from Iran, and NONE of our oil goers through the strait of Hormuz. So why is the price of gas up here??? Do you have ANY idea?? —-May...
Play with this: We get NONE of our oil from Iran, and NONE of our oil goers through the strait of Hormuz. So why is the price of gas up here??? Do you have ANY idea?? —-May...
Read more »
Read more »
Do you think Trump has a low IQ, or is he senile?
Do you think Trump has a low IQ, or is he senile?
Catriona
Catriona
, former Classicist. Stoic. Writer. Wiccan.
Answered April 22
Trump has always been intellectually disabled. Likely brain-damaged at birth, because from very early on, he showed signs of personality defect and psychological disturbanc...
Trump has always been intellectually disabled. Likely brain-damaged at birth, because from very early on, he showed signs of personality defect and psychological disturbanc...
Read more »
Read more »
Are Trump's children embarrassed of him?
Are Trump's children embarrassed of him?
Glen Frey
Glen Frey
, former Taught History for 33 Years.
Answered March 30
Evanka maybe. Apparently the fact that she was part of his first administration, along with her husband, didn’t play well with her social set in New York. At least that was t...
Evanka maybe.
Apparently the fact that she was part of his first administration, along with her husband, didn’t play well with her social set in New York.
At least that was t...
Read more »
Read more »
Read more in No More Trump
Read more in No More Trump
This email was sent by Quora (605 Castro Street, Mountain View, CA 94041).
You were sent this email because you might like
No More Trump
No More Trump
. If you don't want these updates anymore, you can
mute No More Trump
mute No More Trump
or
unsubscribe
unsubscribe
.
https://www.quora.com
https://www.quora.com
Reply
Reply
Forward
Forward
You can't react to a group with an emoji
Calendar
Keep
Tasks
Contacts
Get add-ons
Hide side panel...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Pull requests · screenpipe/screenpipe · GitHub","depth":4,"bounds":{"left":0.3307846,"top":0.05905826,"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.34408244,"top":0.070231445,"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.3307846,"top":0.09177973,"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.34408244,"top":0.10295291,"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.3307846,"top":0.1245012,"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.34408244,"top":0.13567439,"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.3307846,"top":0.15722266,"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.34408244,"top":0.16839585,"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.3307846,"top":0.18994413,"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.34408244,"top":0.20111732,"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.3307846,"top":0.22266561,"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.34408244,"top":0.23383878,"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.3307846,"top":0.25538707,"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.34408244,"top":0.26656026,"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.3307846,"top":0.28810853,"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.34408244,"top":0.29928172,"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.3307846,"top":0.32083002,"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.34408244,"top":0.3320032,"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.3307846,"top":0.35355148,"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.34408244,"top":0.36472467,"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.3307846,"top":0.38627294,"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.34408244,"top":0.39744613,"width":0.030086435,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"How could Trump be profiting off of the war in Iran, since he profits from almost everything he does? - kovaliklukas@gmail.com - Gmail","depth":4,"bounds":{"left":0.3307846,"top":0.41899443,"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":"How could Trump be profiting off of the war in Iran, since he profits from almost everything he does? - kovaliklukas@gmail.com - Gmail","depth":5,"bounds":{"left":0.34408244,"top":0.4301676,"width":0.234375,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.43218085,"top":0.42617717,"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":"(25) Quora","depth":4,"bounds":{"left":0.3307846,"top":0.4517159,"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.34408244,"top":0.46288908,"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.3307846,"top":0.48443735,"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.34408244,"top":0.49561054,"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.3307846,"top":0.5171588,"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.34408244,"top":0.528332,"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.3307846,"top":0.54988027,"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.34408244,"top":0.56105345,"width":0.021609042,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Select: payments - db - Adminer","depth":4,"bounds":{"left":0.3307846,"top":0.5826017,"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":"Select: payments - db - Adminer","depth":5,"bounds":{"left":0.34408244,"top":0.5937749,"width":0.05651596,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":4,"bounds":{"left":0.3307846,"top":0.61532325,"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.34408244,"top":0.62649643,"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.3307846,"top":0.6480447,"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.34408244,"top":0.6592179,"width":0.113696806,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.3336104,"top":0.6823623,"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.3336104,"top":0.97725457,"width":0.010638298,"height":0.02274543},"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.34458113,"top":0.97725457,"width":0.010638298,"height":0.02274543},"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.35571808,"top":0.97725457,"width":0.010638298,"height":0.02274543},"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.36685506,"top":0.97725457,"width":0.010638298,"height":0.02274543},"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.37799203,"top":0.97725457,"width":0.010638298,"height":0.02274543},"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,"bounds":{"left":0.44847074,"top":0.065442935,"width":0.015957447,"height":0.03830806},"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,"bounds":{"left":0.46575797,"top":0.06863528,"width":0.036236703,"height":0.035115723},"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,"bounds":{"left":0.54787236,"top":0.07661612,"width":0.18916224,"height":0.016360734},"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,"bounds":{"left":0.7503325,"top":0.065442935,"width":0.01861702,"height":0.03671189},"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,"bounds":{"left":0.52958775,"top":0.065442935,"width":0.01861702,"height":0.03671189},"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,"bounds":{"left":0.90525264,"top":0.06863528,"width":0.013297873,"height":0.031923383},"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,"bounds":{"left":0.91988033,"top":0.06863528,"width":0.013297873,"height":0.031923383},"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,"bounds":{"left":0.9338431,"top":0.06863528,"width":0.013297873,"height":0.031923383},"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,"bounds":{"left":0.9478058,"top":0.06863528,"width":0.013297873,"height":0.031923383},"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,"bounds":{"left":0.9637633,"top":0.06863528,"width":0.013297873,"height":0.031923383},"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,"bounds":{"left":0.44714096,"top":0.11652035,"width":0.04737367,"height":0.031923383},"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 35 unread","depth":16,"bounds":{"left":0.46575797,"top":0.15722266,"width":0.012466756,"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":"Inbox","depth":17,"bounds":{"left":0.46575797,"top":0.15722266,"width":0.012466756,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"35","depth":16,"bounds":{"left":0.5169548,"top":0.15841979,"width":0.004654255,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Starred","depth":16,"bounds":{"left":0.46575797,"top":0.1763767,"width":0.015625,"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":"Starred","depth":17,"bounds":{"left":0.46575797,"top":0.1763767,"width":0.015625,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Snoozed","depth":16,"bounds":{"left":0.46575797,"top":0.19553073,"width":0.018284574,"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":"Snoozed","depth":17,"bounds":{"left":0.46575797,"top":0.19553073,"width":0.018284574,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Important","depth":17,"bounds":{"left":0.46575797,"top":0.21468475,"width":0.020777926,"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":"Important","depth":18,"bounds":{"left":0.46575797,"top":0.21468475,"width":0.020777926,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sent","depth":16,"bounds":{"left":0.46575797,"top":0.23383878,"width":0.009640957,"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":"Sent","depth":17,"bounds":{"left":0.46575797,"top":0.23383878,"width":0.009640957,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Drafts 8 unread","depth":16,"bounds":{"left":0.46575797,"top":0.2529928,"width":0.013796543,"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":"Drafts","depth":17,"bounds":{"left":0.46575797,"top":0.2529928,"width":0.013796543,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8","depth":16,"bounds":{"left":0.51944816,"top":0.25418994,"width":0.0021609042,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Purchases has menu","depth":16,"bounds":{"left":0.46575797,"top":0.27214685,"width":0.021941489,"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":"Purchases","depth":17,"bounds":{"left":0.46575797,"top":0.27214685,"width":0.021941489,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Social 5202 unread has menu","depth":16,"bounds":{"left":0.46575797,"top":0.29130086,"width":0.013796543,"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":"Social","depth":17,"bounds":{"left":0.46575797,"top":0.29130086,"width":0.013796543,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5,202","depth":16,"bounds":{"left":0.5114694,"top":0.292498,"width":0.010139627,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Updates 8797 unread has menu","depth":16,"bounds":{"left":0.46575797,"top":0.3104549,"width":0.018949468,"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":"Updates","depth":17,"bounds":{"left":0.46575797,"top":0.3104549,"width":0.018949468,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8,797","depth":16,"bounds":{"left":0.5121343,"top":0.31165203,"width":0.009474734,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Forums 6100 unread has menu","depth":16,"bounds":{"left":0.46575797,"top":0.32960895,"width":0.016788565,"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":"Forums","depth":17,"bounds":{"left":0.46575797,"top":0.32960895,"width":0.016788565,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6,100","depth":16,"bounds":{"left":0.5114694,"top":0.33080608,"width":0.010139627,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Promotions 38752 unread has menu","depth":16,"bounds":{"left":0.46575797,"top":0.34876296,"width":0.025930852,"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":"Promotions","depth":17,"bounds":{"left":0.46575797,"top":0.34876296,"width":0.025930852,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"38,752","depth":16,"bounds":{"left":0.5099734,"top":0.3499601,"width":0.011635638,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"More labels","depth":12,"bounds":{"left":0.44448137,"top":0.36552274,"width":0.07978723,"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":"More","depth":14,"bounds":{"left":0.46575797,"top":0.367917,"width":0.010804521,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Labels","depth":11,"bounds":{"left":0.453125,"top":0.40702313,"width":0.061835106,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Labels","depth":12,"bounds":{"left":0.453125,"top":0.40702313,"width":0.016456118,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create new label","depth":11,"bounds":{"left":0.5149601,"top":0.40742218,"width":0.0066489363,"height":0.015961692},"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,"bounds":{"left":0.46575797,"top":0.43535516,"width":0.055352394,"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":"[Imap]/Nevyžiadaná pošta","depth":17,"bounds":{"left":0.46575797,"top":0.43535516,"width":0.055352394,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"arch has menu","depth":16,"bounds":{"left":0.46575797,"top":0.45450917,"width":0.009474734,"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":"arch","depth":17,"bounds":{"left":0.46575797,"top":0.45450917,"width":0.009474734,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Deleted Items has menu","depth":16,"bounds":{"left":0.46575797,"top":0.4736632,"width":0.029089095,"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":"Deleted Items","depth":17,"bounds":{"left":0.46575797,"top":0.4736632,"width":0.029089095,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Fibank 1229 unread has menu","depth":16,"bounds":{"left":0.46575797,"top":0.49281725,"width":0.01512633,"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":"Fibank","depth":17,"bounds":{"left":0.46575797,"top":0.49281725,"width":0.01512633,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1,229","depth":16,"bounds":{"left":0.5124667,"top":0.49401435,"width":0.009142287,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"FL 6 unread has menu","depth":16,"bounds":{"left":0.46575797,"top":0.5119713,"width":0.005319149,"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":"FL","depth":17,"bounds":{"left":0.46575797,"top":0.5119713,"width":0.005319149,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6","depth":16,"bounds":{"left":0.5192819,"top":0.5131684,"width":0.0023271276,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Hardware & Software has menu","depth":16,"bounds":{"left":0.46575797,"top":0.5311253,"width":0.044714097,"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":"Hardware & Software","depth":17,"bounds":{"left":0.46575797,"top":0.5311253,"width":0.044714097,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"HOSTING 5 unread has menu","depth":16,"bounds":{"left":0.46575797,"top":0.5502793,"width":0.02144282,"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":"HOSTING","depth":17,"bounds":{"left":0.46575797,"top":0.5502793,"width":0.02144282,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5","depth":16,"bounds":{"left":0.51944816,"top":0.5514765,"width":0.0021609042,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Infected Items has menu","depth":16,"bounds":{"left":0.46575797,"top":0.56943333,"width":0.030086435,"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":"Infected Items","depth":17,"bounds":{"left":0.46575797,"top":0.56943333,"width":0.030086435,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"jiminny-github 7487 unread has menu","depth":16,"bounds":{"left":0.46575797,"top":0.5885874,"width":0.03324468,"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":"jiminny-github","depth":17,"bounds":{"left":0.46575797,"top":0.5885874,"width":0.03324468,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7,487","depth":16,"bounds":{"left":0.5124667,"top":0.5897845,"width":0.009142287,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Junk E-mail 219 unread has menu","depth":16,"bounds":{"left":0.46575797,"top":0.6077414,"width":0.026761968,"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":"Junk E-mail","depth":17,"bounds":{"left":0.46575797,"top":0.6077414,"width":0.026761968,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"219","depth":16,"bounds":{"left":0.515625,"top":0.6089386,"width":0.005984043,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Kontakty has menu","depth":16,"bounds":{"left":0.46575797,"top":0.6268954,"width":0.018450798,"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":"Kontakty","depth":17,"bounds":{"left":0.46575797,"top":0.6268954,"width":0.018450798,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sent Items has menu","depth":16,"bounds":{"left":0.46575797,"top":0.6460495,"width":0.022273935,"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":"Sent Items","depth":17,"bounds":{"left":0.46575797,"top":0.6460495,"width":0.022273935,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"WORK 848 unread has menu","depth":16,"bounds":{"left":0.46575797,"top":0.6652035,"width":0.014461436,"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":"WORK","depth":17,"bounds":{"left":0.46575797,"top":0.6652035,"width":0.014461436,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"848","depth":16,"bounds":{"left":0.5149601,"top":0.6664006,"width":0.0066489363,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"z centra 1274 unread has menu","depth":16,"bounds":{"left":0.46575797,"top":0.6843575,"width":0.018118352,"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":"z centra","depth":17,"bounds":{"left":0.46575797,"top":0.6843575,"width":0.018118352,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1,274","depth":16,"bounds":{"left":0.5127992,"top":0.6855547,"width":0.00880984,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"More labels","depth":12,"bounds":{"left":0.44448137,"top":0.70111734,"width":0.07978723,"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":"More","depth":14,"bounds":{"left":0.46575797,"top":0.7035116,"width":0.010804521,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Back to Inbox","depth":11,"bounds":{"left":0.5349069,"top":0.121308856,"width":0.0066489363,"height":0.015961692},"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,"bounds":{"left":0.55352396,"top":0.121308856,"width":0.0066489363,"height":0.015961692},"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,"bounds":{"left":0.5681516,"top":0.121308856,"width":0.0066489363,"height":0.015961692},"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,"bounds":{"left":0.5827792,"top":0.121308856,"width":0.0066489363,"height":0.015961692},"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,"bounds":{"left":0.60272604,"top":0.121308856,"width":0.0066489363,"height":0.015961692},"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,"bounds":{"left":0.61735374,"top":0.121308856,"width":0.0066489363,"height":0.015961692},"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,"bounds":{"left":0.6306516,"top":0.121308856,"width":0.0066489363,"height":0.015961692},"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":"40","depth":11,"bounds":{"left":0.88513964,"top":0.12330407,"width":0.004986702,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"of","depth":11,"bounds":{"left":0.89012635,"top":0.12330407,"width":0.0056515955,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21,245","depth":11,"bounds":{"left":0.89577794,"top":0.12330407,"width":0.011469414,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Newer","depth":10,"bounds":{"left":0.91389626,"top":0.121308856,"width":0.0066489363,"height":0.015961692},"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,"bounds":{"left":0.9271942,"top":0.121308856,"width":0.0066489363,"height":0.015961692},"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,"bounds":{"left":0.93916225,"top":0.121308856,"width":0.0066489363,"height":0.015961692},"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,"bounds":{"left":0.94581115,"top":0.121308856,"width":0.0066489363,"height":0.015961692},"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,"bounds":{"left":0.93583775,"top":0.15961692,"width":0.013297873,"height":0.031923383},"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,"bounds":{"left":0.9478058,"top":0.15961692,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"How could Trump be profiting off of the war in Iran, since he profits from almost everything he does?","depth":13,"bounds":{"left":0.55352396,"top":0.16440542,"width":0.33510637,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How could Trump be profiting off of the war in Iran, since he profits from almost everything he does?","depth":14,"bounds":{"left":0.55352396,"top":0.16440542,"width":0.33178192,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Not important","depth":14,"bounds":{"left":0.8853058,"top":0.15921788,"width":0.013297873,"height":0.031923383},"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,"bounds":{"left":0.89860374,"top":0.16839585,"width":0.011801862,"height":0.014365523},"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,"bounds":{"left":0.9104056,"top":0.16839585,"width":0.0048204786,"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":"Quora Suggested Spaces nomoretrump-space@quora.com Unsubscribe","depth":23,"bounds":{"left":0.55352396,"top":0.20271349,"width":0.16140293,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXCell","text":"Quora Suggested Spaces nomoretrump-space@quora.com","depth":24,"bounds":{"left":0.55352396,"top":0.2047087,"width":0.12333777,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Quora Suggested Spaces","depth":25,"bounds":{"left":0.55352396,"top":0.20351157,"width":0.056848403,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"nomoretrump-space@quora.com","depth":25,"bounds":{"left":0.6135306,"top":0.2047087,"width":0.060339097,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Unsubscribe","depth":25,"bounds":{"left":0.67952126,"top":0.20271349,"width":0.035405584,"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":"Unsubscribe","depth":26,"bounds":{"left":0.68351066,"top":0.20351157,"width":0.027426861,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Mon 4 May, 08:32 (5 days ago)","depth":20,"bounds":{"left":0.8494016,"top":0.20271349,"width":0.05518617,"height":0.015961692},"on_screen":true,"help_text":"4 May 2026, 08:32","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Mon 4 May, 08:32 (5 days ago)","depth":21,"bounds":{"left":0.8494016,"top":0.2047087,"width":0.05518617,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Not starred","depth":21,"bounds":{"left":0.9112367,"top":0.20271349,"width":0.0066489363,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"You can't react to a group with an emoji","depth":21,"bounds":{"left":0.9212101,"top":0.19473264,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Reply","depth":21,"bounds":{"left":0.93450797,"top":0.19473264,"width":0.013297873,"height":0.031923383},"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,"bounds":{"left":0.9478058,"top":0.19473264,"width":0.013297873,"height":0.031923383},"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,"bounds":{"left":0.55352396,"top":0.22067039,"width":0.004654255,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"me","depth":24,"bounds":{"left":0.5581782,"top":0.22067039,"width":0.0056515955,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Show details","depth":23,"bounds":{"left":0.56515956,"top":0.22186752,"width":0.0039893617,"height":0.009577015},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"No More Trump No More Trump • 107.4K followers Sustained resistance to the Traitorous Mister Trump, his clones, and his MAGATS.","depth":26,"bounds":{"left":0.6683843,"top":0.26735833,"width":0.17453457,"height":0.15003991},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"How could Trump be profiting off of the war in Iran, since he profits from almost everything he does?","depth":26,"bounds":{"left":0.6683843,"top":0.4385475,"width":0.17037898,"height":0.039505187},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How could Trump be profiting off of the war in Iran, since he profits from almost everything he does?","depth":27,"bounds":{"left":0.6683843,"top":0.4385475,"width":0.17037898,"height":0.039505187},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"John Mooney","depth":28,"bounds":{"left":0.6687167,"top":0.48643255,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"John Mooney","depth":29,"bounds":{"left":0.6850067,"top":0.48643255,"width":0.032579787,"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":", former USN, Retired at Aviation Ordnaceman (1967-1984)","depth":29,"bounds":{"left":0.6850067,"top":0.48643255,"width":0.13730054,"height":0.029130088},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Answered April 25","depth":29,"bounds":{"left":0.6850067,"top":0.51835597,"width":0.03673537,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Play with this: We get NONE of our oil from Iran, and NONE of our oil goers through the strait of Hormuz. So why is the price of gas up here??? Do you have ANY idea?? —-May...","depth":26,"bounds":{"left":0.6683843,"top":0.5510774,"width":0.17453457,"height":0.070231445},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Play with this: We get NONE of our oil from Iran, and NONE of our oil goers through the strait of Hormuz. So why is the price of gas up here??? Do you have ANY idea?? —-May...","depth":28,"bounds":{"left":0.6683843,"top":0.55307263,"width":0.17037898,"height":0.053072624},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Read more »","depth":26,"bounds":{"left":0.6683843,"top":0.62330407,"width":0.02925532,"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":"Read more »","depth":27,"bounds":{"left":0.6683843,"top":0.62330407,"width":0.02925532,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Do you think Trump has a low IQ, or is he senile?","depth":26,"bounds":{"left":0.6683843,"top":0.6867518,"width":0.13646941,"height":0.018355945},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Do you think Trump has a low IQ, or is he senile?","depth":27,"bounds":{"left":0.6683843,"top":0.6867518,"width":0.13646941,"height":0.018355945},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Catriona","depth":28,"bounds":{"left":0.6687167,"top":0.7138867,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Catriona","depth":29,"bounds":{"left":0.6850067,"top":0.7134876,"width":0.020777926,"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":", former Classicist. Stoic. Writer. Wiccan.","depth":29,"bounds":{"left":0.70578456,"top":0.7134876,"width":0.09291888,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Answered April 22","depth":29,"bounds":{"left":0.6850067,"top":0.7310455,"width":0.03673537,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Trump has always been intellectually disabled. Likely brain-damaged at birth, because from very early on, he showed signs of personality defect and psychological disturbanc...","depth":26,"bounds":{"left":0.6683843,"top":0.76576215,"width":0.17453457,"height":0.070231445},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Trump has always been intellectually disabled. Likely brain-damaged at birth, because from very early on, he showed signs of personality defect and psychological disturbanc...","depth":28,"bounds":{"left":0.6683843,"top":0.76775736,"width":0.16489361,"height":0.053072624},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Read more »","depth":26,"bounds":{"left":0.6683843,"top":0.83798885,"width":0.02925532,"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":"Read more »","depth":27,"bounds":{"left":0.6683843,"top":0.83798885,"width":0.02925532,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Are Trump's children embarrassed of him?","depth":26,"bounds":{"left":0.6683843,"top":0.90143657,"width":0.12167553,"height":0.018355945},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Are Trump's children embarrassed of him?","depth":27,"bounds":{"left":0.6683843,"top":0.90143657,"width":0.12167553,"height":0.018355945},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Glen Frey","depth":28,"bounds":{"left":0.6687167,"top":0.9285714,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Glen Frey","depth":29,"bounds":{"left":0.6850067,"top":0.9285714,"width":0.023105053,"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":", former Taught History for 33 Years.","depth":29,"bounds":{"left":0.7081117,"top":0.9285714,"width":0.083277926,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Answered March 30","depth":29,"bounds":{"left":0.6850067,"top":0.94612926,"width":0.040226065,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Evanka maybe. Apparently the fact that she was part of his first administration, along with her husband, didn’t play well with her social set in New York. At least that was t...","depth":26,"bounds":{"left":0.6683843,"top":0.98044693,"width":0.17453457,"height":0.019553065},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Evanka maybe.","depth":28,"bounds":{"left":0.6683843,"top":0.9828412,"width":0.034242023,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Apparently the fact that she was part of his first administration, along with her husband, didn’t play well with her social set in New York.","depth":28,"bounds":{"left":0.6683843,"top":1.0,"width":0.1690492,"height":-0.014764547},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"At least that was t...","depth":28,"bounds":{"left":0.6683843,"top":1.0,"width":0.045212764,"height":-0.06584203},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Read more »","depth":26,"bounds":{"left":0.6683843,"top":1.0,"width":0.02925532,"height":-0.09776533},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Read more »","depth":27,"bounds":{"left":0.6683843,"top":1.0,"width":0.02925532,"height":-0.09776533},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Read more in No More Trump","depth":25,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Read more in No More Trump","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"This email was sent by Quora (605 Castro Street, Mountain View, CA 94041).","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You were sent this email because you might like","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"No More Trump","depth":25,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"No More Trump","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":". If you don't want these updates anymore, you can","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"mute No More Trump","depth":25,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"mute No More Trump","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"or","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"unsubscribe","depth":25,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"unsubscribe","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"https://www.quora.com","depth":25,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"https://www.quora.com","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Reply","depth":14,"bounds":{"left":0.55352396,"top":0.9537111,"width":0.034574468,"height":0.028731046},"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.56865025,"top":0.96089387,"width":0.012300532,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Forward","depth":14,"bounds":{"left":0.59075797,"top":0.9537111,"width":0.03723404,"height":0.028731046},"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.6043883,"top":0.96089387,"width":0.017952127,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"You can't react to a group with an emoji","depth":15,"bounds":{"left":0.6306516,"top":0.9537111,"width":0.011968086,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Calendar","depth":10,"bounds":{"left":0.9630984,"top":0.110135674,"width":0.01861702,"height":0.044692736},"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,"bounds":{"left":0.9630984,"top":0.15482841,"width":0.01861702,"height":0.044692736},"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,"bounds":{"left":0.9630984,"top":0.19952115,"width":0.01861702,"height":0.044692736},"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,"bounds":{"left":0.9630984,"top":0.2442139,"width":0.01861702,"height":0.044692736},"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,"bounds":{"left":0.9630984,"top":0.31524342,"width":0.01861702,"height":0.044692736},"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,"bounds":{"left":0.9630984,"top":0.96249,"width":0.01861702,"height":0.037509978},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-8279124367963442038
|
2553673871296219530
|
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
How could Trump be profiting off of the war in Iran, since he profits from almost everything he does? - [EMAIL] - Gmail
How could Trump be profiting off of the war in Iran, since he profits from almost everything he does? - [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 35 unread
Inbox
35
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 8797 unread has menu
Updates
8,797
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
40
of
21,245
Newer
Older
Input tools on/off (Ctrl-Shift-K)
Select input tool
Print all
In new window
How could Trump be profiting off of the war in Iran, since he profits from almost everything he does?
How could Trump be profiting off of the war in Iran, since he profits from almost everything he does?
Not important
Search for all messages with label Inbox
Remove label Inbox from this conversation
Quora Suggested Spaces [EMAIL] Unsubscribe
Quora Suggested Spaces [EMAIL]
Quora Suggested Spaces
[EMAIL]
Unsubscribe
Unsubscribe
Mon 4 May, 08:32 (5 days ago)
Mon 4 May, 08:32 (5 days ago)
Not starred
You can't react to a group with an emoji
Reply
More message options
to
me
Show details
No More Trump No More Trump • 107.4K followers Sustained resistance to the Traitorous Mister Trump, his clones, and his MAGATS.
How could Trump be profiting off of the war in Iran, since he profits from almost everything he does?
How could Trump be profiting off of the war in Iran, since he profits from almost everything he does?
John Mooney
John Mooney
, former USN, Retired at Aviation Ordnaceman (1967-1984)
Answered April 25
Play with this: We get NONE of our oil from Iran, and NONE of our oil goers through the strait of Hormuz. So why is the price of gas up here??? Do you have ANY idea?? —-May...
Play with this: We get NONE of our oil from Iran, and NONE of our oil goers through the strait of Hormuz. So why is the price of gas up here??? Do you have ANY idea?? —-May...
Read more »
Read more »
Do you think Trump has a low IQ, or is he senile?
Do you think Trump has a low IQ, or is he senile?
Catriona
Catriona
, former Classicist. Stoic. Writer. Wiccan.
Answered April 22
Trump has always been intellectually disabled. Likely brain-damaged at birth, because from very early on, he showed signs of personality defect and psychological disturbanc...
Trump has always been intellectually disabled. Likely brain-damaged at birth, because from very early on, he showed signs of personality defect and psychological disturbanc...
Read more »
Read more »
Are Trump's children embarrassed of him?
Are Trump's children embarrassed of him?
Glen Frey
Glen Frey
, former Taught History for 33 Years.
Answered March 30
Evanka maybe. Apparently the fact that she was part of his first administration, along with her husband, didn’t play well with her social set in New York. At least that was t...
Evanka maybe.
Apparently the fact that she was part of his first administration, along with her husband, didn’t play well with her social set in New York.
At least that was t...
Read more »
Read more »
Read more in No More Trump
Read more in No More Trump
This email was sent by Quora (605 Castro Street, Mountain View, CA 94041).
You were sent this email because you might like
No More Trump
No More Trump
. If you don't want these updates anymore, you can
mute No More Trump
mute No More Trump
or
unsubscribe
unsubscribe
.
https://www.quora.com
https://www.quora.com
Reply
Reply
Forward
Forward
You can't react to a group with an emoji
Calendar
Keep
Tasks
Contacts
Get add-ons
Hide side panel...
|
12306
|
NULL
|
NULL
|
NULL
|
|
9334
|
NULL
|
0
|
2026-05-08T12:41:25.547868+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-08/1778 /Users/lukas/.screenpipe/data/data/2026-05-08/1778244085547_m2.jpg...
|
Firefox
|
Jy 20820 es reindex stream model hydration by Vasi Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app — Work...
|
True
|
github.com/jiminny/app/pull/12059/changes#diff-f77 github.com/jiminny/app/pull/12059/changes#diff-f77c5793308caa3e764a033422493121a1329dd953a89f3dde4a9386622f22f9...
|
monitor_2
|
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
Unnamed Group
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST [URL_WITH_CREDENTIALS] -18,4 +18,8 @@ public function getIndex(): string;
18
public
function
getSearchKey
():
int
;
18
public
function
getSearchKey
():
int
;
19
19
20
public
function
getIndexableAttributes
():
array
;
20
public
function
getIndexableAttributes
():
array
;
21
+
22
+
public
function
isDeleted
():
bool
;
23
+
24
+
public
function
setRelations
(
array
$
relations
);
21
}
25
}
Original file line number
@@ -18,4 +18,8 @@ public function getIndex(): string;
18
19
20
21
Original file line
@@ -18,4 +18,8 @@ public function getIndex(): string;
public
function
getSearchKey
():
int
;
public
function
getIndexableAttributes
():
array
;
}
Diff line number
@@ -18,4 +18,8 @@ public function getIndex(): string;
18
19
20
21
22
23
24
25
Diff line change
@@ -18,4 +18,8 @@ public function getIndex(): string;
public
function
getSearchKey
():
int
;
public
function
getIndexableAttributes
():
array
;
+
+
public
function
isDeleted
():
bool
;
+
+
public
function
setRelations
(
array
$
relations
);
}
Collapse file
app/Component/ES/Processor/Actions/LoadDocumentsAction.php
app/Component/ES/Processor/Actions/LoadDocumentsAction.php
app/Component/ES/Processor/Actions/LoadDocumentsAction.php
Copy file name to clipboard
Expand all lines: app/Component/ES/Processor/Actions/LoadDocumentsAction.php
Lines changed: 39 additions & 44 deletions
Not Viewed
Viewed
Comment on this file
More options
Original file line number
Original file line
Diff line number
Diff line change
@@ -5,69 +5,64 @@
5
namespace
Jiminny
\
Component
\
ES
\
Processor
\
Actions
;
5
namespace
Jiminny
\
Component
\
ES
\
Processor
\
Actions
;
6
6
7
use
Elastica
\
Document
;
7
use
Elastica
\
Document
;
8
-
use
Illuminate
\
Support
\
Collection
;
9
use
Jiminny
\
Component
\
ElasticSearch
\
Contract
\
Searchable
;
8
use
Jiminny
\
Component
\
ElasticSearch
\
Contract
\
Searchable
;
10
use
Jiminny
\...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.2237367,"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":"Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.23703457,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Unnamed Group","depth":4,"bounds":{"left":0.2265625,"top":0.08978452,"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":"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,"bounds":{"left":0.2265625,"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":"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,"bounds":{"left":0.23969415,"top":0.1245012,"width":0.4644282,"height":0.010774142},"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,"bounds":{"left":0.2265625,"top":0.14604948,"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":"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,"bounds":{"left":0.23969415,"top":0.15722266,"width":0.4644282,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.2237367,"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":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.23703457,"top":0.18994413,"width":0.10721409,"height":0.010774142},"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,"bounds":{"left":0.2237367,"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 20807 check various issues with stages by nikolaybiaivanov · Pull Request #12041 · jiminny/app","depth":5,"bounds":{"left":0.23703457,"top":0.22266561,"width":0.17037898,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.2237367,"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":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.23703457,"top":0.25538707,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20818 move ask jiminny reports to its own datadog metric by LakyLak · Pull Request #12056 · jiminny/app","depth":4,"bounds":{"left":0.2237367,"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-20818 move ask jiminny reports to its own datadog metric by LakyLak · Pull Request #12056 · jiminny/app","depth":5,"bounds":{"left":0.23703457,"top":0.28810853,"width":0.18899602,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Userpilot | Ask Jiminny Report Generated","depth":4,"bounds":{"left":0.2237367,"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":"Userpilot | Ask Jiminny Report Generated","depth":5,"bounds":{"left":0.23703457,"top":0.32083002,"width":0.07164229,"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.2237367,"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-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app","depth":5,"bounds":{"left":0.23703457,"top":0.35355148,"width":0.19331782,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Problem loading page","depth":4,"bounds":{"left":0.2237367,"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":"Problem loading page","depth":5,"bounds":{"left":0.23703457,"top":0.38627294,"width":0.037898935,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Search the CRM - HubSpot docs","depth":4,"bounds":{"left":0.2237367,"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":"Search the CRM - HubSpot docs","depth":5,"bounds":{"left":0.23703457,"top":0.41899443,"width":0.05651596,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.2237367,"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":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.23703457,"top":0.4517159,"width":0.013131649,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.2237367,"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":"New Tab","depth":5,"bounds":{"left":0.23703457,"top":0.48443735,"width":0.014960106,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.2237367,"top":0.5059856,"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.23703457,"top":0.5171588,"width":0.014960106,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"AI Features | Datadog","depth":4,"bounds":{"left":0.2237367,"top":0.5387071,"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":"AI Features | Datadog","depth":5,"bounds":{"left":0.23703457,"top":0.54988027,"width":0.037400264,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 20493 smart instant nudge pre filtering by nikolaybiaivanov · Pull Request #12053 · jiminny/app","depth":4,"bounds":{"left":0.2237367,"top":0.5714286,"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 20493 smart instant nudge pre filtering by nikolaybiaivanov · Pull Request #12053 · jiminny/app","depth":5,"bounds":{"left":0.23703457,"top":0.5826017,"width":0.17037898,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.2237367,"top":0.60415006,"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.23703457,"top":0.61532325,"width":0.039228722,"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.2237367,"top":0.6368715,"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 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app","depth":5,"bounds":{"left":0.23703457,"top":0.6480447,"width":0.16888298,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.29105717,"top":0.6440543,"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.2265625,"top":0.6711891,"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.2265625,"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":"Close Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23753324,"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.2486702,"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.25980717,"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.27094415,"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":"AI Chat settings","depth":7,"bounds":{"left":0.4084109,"top":0.055067837,"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,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"bounds":{"left":0.42037898,"top":0.055067837,"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":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.41771942,"top":0.103751,"width":0.013297873,"height":0.031923383},"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":"Main menu","depth":12,"bounds":{"left":0.3073471,"top":0.103751,"width":0.013297873,"height":0.031923383},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New chat","depth":12,"bounds":{"left":0.32064494,"top":0.10454908,"width":0.028590426,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Gemini","depth":15,"bounds":{"left":0.32330453,"top":0.10973663,"width":0.021941489,"height":0.020351157},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"PRO","depth":11,"bounds":{"left":0.40093085,"top":0.110135674,"width":0.014793883,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"PRO","depth":13,"bounds":{"left":0.4035904,"top":0.112529926,"width":0.009474734,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"bounds":{"left":0.30302528,"top":0.14764565,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"bounds":{"left":0.30302528,"top":0.15003991,"width":0.1200133,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hi Lukas","depth":23,"bounds":{"left":0.31000665,"top":0.22027135,"width":0.027759308,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Where should we start?","depth":22,"bounds":{"left":0.31000665,"top":0.24261771,"width":0.1165226,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Where should we start?","depth":24,"bounds":{"left":0.31000665,"top":0.24102154,"width":0.11386303,"height":0.032322425},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"🖼️ Create image, button, tap to use tool","depth":22,"bounds":{"left":0.31000665,"top":0.2905028,"width":0.049534574,"height":0.03830806},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"🖼️ Create image","depth":24,"bounds":{"left":0.3153258,"top":0.30127692,"width":0.038896278,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"🎸 Create music, button, tap to use tool","depth":22,"bounds":{"left":0.31000665,"top":0.33519554,"width":0.04886968,"height":0.03830806},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"🎸 Create music","depth":24,"bounds":{"left":0.3153258,"top":0.34596968,"width":0.038231384,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help me learn, button, tap to use tool","depth":22,"bounds":{"left":0.31000665,"top":0.37988827,"width":0.044049203,"height":0.03830806},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help me learn","depth":24,"bounds":{"left":0.3153258,"top":0.39106146,"width":0.033410903,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Boost my day, button, tap to use tool","depth":22,"bounds":{"left":0.31000665,"top":0.424581,"width":0.04338431,"height":0.03830806},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Boost my day","depth":24,"bounds":{"left":0.3153258,"top":0.43575418,"width":0.03274601,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Write anything, button, tap to use tool","depth":22,"bounds":{"left":0.31000665,"top":0.46927375,"width":0.045711435,"height":0.03830806},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Write anything","depth":24,"bounds":{"left":0.3153258,"top":0.48044693,"width":0.03507314,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"You are seasoned code reviewer and your task is to make detailed code review of summari","depth":20,"bounds":{"left":0.31665558,"top":0.8184357,"width":0.10638298,"height":0.057462092},"on_screen":true,"value":"You are seasoned code reviewer and your task is to make detailed code review of summari","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"You are seasoned code reviewer and your task is to make detailed code review of summari","depth":22,"bounds":{"left":0.31665558,"top":0.82003194,"width":0.10139628,"height":0.054668795},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"bounds":{"left":0.31266624,"top":0.89265764,"width":0.013297873,"height":0.031923383},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"bounds":{"left":0.32862368,"top":0.89265764,"width":0.013297873,"height":0.031923383},"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":"Open mode picker","depth":20,"bounds":{"left":0.3856383,"top":0.8902634,"width":0.026097074,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"bounds":{"left":0.39095744,"top":0.8990423,"width":0.007480053,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"bounds":{"left":0.41306517,"top":0.8894653,"width":0.013962766,"height":0.033519555},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Summarize page","depth":7,"bounds":{"left":0.30867687,"top":0.95730245,"width":0.053523935,"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":"Summarize page","depth":9,"bounds":{"left":0.31432846,"top":0.96249,"width":0.042220745,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Skip to content","depth":7,"bounds":{"left":0.43916222,"top":0.0,"width":0.0003324468,"height":0.0007980846},"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":8,"bounds":{"left":0.43916222,"top":0.0,"width":0.0029920214,"height":0.21468475},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":11,"bounds":{"left":0.44448137,"top":0.0,"width":0.010638298,"height":0.025538707},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":10,"bounds":{"left":0.45910904,"top":0.0,"width":0.010638298,"height":0.025538707},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":13,"bounds":{"left":0.47240692,"top":0.0,"width":0.018949468,"height":0.025538707},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":15,"bounds":{"left":0.4744016,"top":0.0,"width":0.014960106,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":13,"bounds":{"left":0.49634308,"top":0.0,"width":0.017785905,"height":0.025538707},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":15,"bounds":{"left":0.49833778,"top":0.0,"width":0.008477394,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":10,"bounds":{"left":0.8171542,"top":0.0,"width":0.06565824,"height":0.025538707},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":13,"bounds":{"left":0.8294548,"top":0.0,"width":0.011801862,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":13,"bounds":{"left":0.84258646,"top":0.0,"width":0.002493351,"height":0.011572227},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":13,"bounds":{"left":0.8465758,"top":0.0,"width":0.021276595,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":11,"bounds":{"left":0.88480717,"top":0.0,"width":0.010638298,"height":0.025538707},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":10,"bounds":{"left":0.89511305,"top":0.0,"width":0.008643617,"height":0.025538707},"on_screen":false,"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":10,"bounds":{"left":0.91173536,"top":0.0,"width":0.01662234,"height":0.025538707},"on_screen":false,"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":10,"bounds":{"left":0.9310173,"top":0.0,"width":0.010638298,"height":0.025538707},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":10,"bounds":{"left":0.94431514,"top":0.0,"width":0.010638298,"height":0.025538707},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":10,"bounds":{"left":0.95761305,"top":0.0,"width":0.010638298,"height":0.025538707},"on_screen":false,"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":10,"bounds":{"left":0.9709109,"top":0.0,"width":0.010638298,"height":0.025538707},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":10,"bounds":{"left":0.98420876,"top":0.0,"width":0.010638298,"height":0.025538707},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":10,"bounds":{"left":0.43882978,"top":0.0,"width":0.0003324468,"height":0.0007980846},"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":11,"bounds":{"left":0.43882978,"top":0.0,"width":0.0787899,"height":0.023144454},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":13,"bounds":{"left":0.44448137,"top":0.0,"width":0.025099734,"height":0.026336791},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":15,"bounds":{"left":0.4552859,"top":0.0,"width":0.011469414,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (33)","depth":13,"bounds":{"left":0.4722407,"top":0.0,"width":0.05518617,"height":0.026336791},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":15,"bounds":{"left":0.48287898,"top":0.0,"width":0.02925532,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":15,"bounds":{"left":0.5147939,"top":0.0,"width":0.0029920214,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"33","depth":15,"bounds":{"left":0.5177859,"top":0.0,"width":0.005817819,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":15,"bounds":{"left":0.52360374,"top":0.0,"width":0.0016622341,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":13,"bounds":{"left":0.53008646,"top":0.0,"width":0.029089095,"height":0.026336791},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":15,"bounds":{"left":0.54105717,"top":0.0,"width":0.014960106,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":13,"bounds":{"left":0.5618351,"top":0.0,"width":0.03025266,"height":0.026336791},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":15,"bounds":{"left":0.5728058,"top":0.0,"width":0.016123671,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":13,"bounds":{"left":0.59474736,"top":0.0,"width":0.022938829,"height":0.026336791},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":15,"bounds":{"left":0.60555184,"top":0.0,"width":0.009142287,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality (2)","depth":13,"bounds":{"left":0.6203458,"top":0.0,"width":0.06798537,"height":0.026336791},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":15,"bounds":{"left":0.6321476,"top":0.0,"width":0.04255319,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":15,"bounds":{"left":0.67852396,"top":0.0,"width":0.0029920214,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2","depth":15,"bounds":{"left":0.68151593,"top":0.0,"width":0.0026595744,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":15,"bounds":{"left":0.68417555,"top":0.0,"width":0.0018284575,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":13,"bounds":{"left":0.6909907,"top":0.0,"width":0.031083776,"height":0.026336791},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":15,"bounds":{"left":0.70212764,"top":0.0,"width":0.016788565,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":13,"bounds":{"left":0.72473407,"top":0.0,"width":0.032081116,"height":0.026336791},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":15,"bounds":{"left":0.73603725,"top":0.0,"width":0.01761968,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":11,"bounds":{"left":0.45279256,"top":0.0023942539,"width":0.0003324468,"height":0.016759777},"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":12,"bounds":{"left":0.45279256,"top":0.003990423,"width":0.039228722,"height":0.013567438},"on_screen":false,"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":11,"bounds":{"left":0.45279256,"top":0.003990423,"width":0.2159242,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":11,"bounds":{"left":0.6687167,"top":0.003990423,"width":0.04055851,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":12,"bounds":{"left":0.6687167,"top":0.003990423,"width":0.04055851,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":11,"bounds":{"left":0.70927525,"top":0.003990423,"width":0.08261303,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":11,"bounds":{"left":0.7918883,"top":0.003990423,"width":0.05219415,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":12,"bounds":{"left":0.7918883,"top":0.003990423,"width":0.05219415,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":11,"bounds":{"left":0.8440825,"top":0.003990423,"width":0.0013297872,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":10,"bounds":{"left":0.9865359,"top":0.0,"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":"Jy 20820 es reindex stream model hydration #12059 Edit title","depth":13,"bounds":{"left":0.44980052,"top":0.050678372,"width":0.25382313,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jy 20820 es reindex stream model hydration","depth":14,"bounds":{"left":0.44980052,"top":0.051476456,"width":0.20246011,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"#","depth":15,"bounds":{"left":0.6549202,"top":0.051476456,"width":0.0066489363,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12059","depth":15,"bounds":{"left":0.6615692,"top":0.051476456,"width":0.030086435,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Edit title","depth":14,"bounds":{"left":0.69298536,"top":0.05387071,"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":"AXMenuButton","text":"Preview","depth":13,"bounds":{"left":0.9584442,"top":0.05865922,"width":0.031083776,"height":0.022346368},"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":"Preview","depth":15,"bounds":{"left":0.9637633,"top":0.06344773,"width":0.01512633,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Awaiting approval","depth":13,"bounds":{"left":0.86818486,"top":0.057063047,"width":0.055352394,"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":"Awaiting approval","depth":15,"bounds":{"left":0.88048536,"top":0.06304868,"width":0.03873005,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Code","depth":13,"bounds":{"left":0.9261968,"top":0.057063047,"width":0.02825798,"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":"Code","depth":15,"bounds":{"left":0.9305186,"top":0.06304868,"width":0.011635638,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open","depth":13,"bounds":{"left":0.46043882,"top":0.09497207,"width":0.011968086,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Vasil-Jiminny","depth":15,"bounds":{"left":0.47905585,"top":0.09177973,"width":0.03025266,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Vasil-Jiminny","depth":16,"bounds":{"left":0.47905585,"top":0.0933759,"width":0.03025266,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"wants to merge 35 commits into","depth":15,"bounds":{"left":0.5106383,"top":0.0933759,"width":0.06931516,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"master","depth":15,"bounds":{"left":0.5812833,"top":0.091380686,"width":0.018284574,"height":0.017557861},"on_screen":true,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"master","depth":16,"bounds":{"left":0.58327794,"top":0.09457303,"width":0.014295213,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"from","depth":16,"bounds":{"left":0.6008976,"top":0.0933759,"width":0.009973404,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20820-es-reindex-stream-model-hydration","depth":16,"bounds":{"left":0.6122008,"top":0.091380686,"width":0.10488697,"height":0.017557861},"on_screen":true,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20820-es-reindex-stream-model-hydration","depth":17,"bounds":{"left":0.61419547,"top":0.09457303,"width":0.1008976,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy head branch name to clipboard","depth":16,"bounds":{"left":0.7184175,"top":0.088986434,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lines changed: 363 additions & 140 deletions","depth":14,"bounds":{"left":0.95212764,"top":0.1452514,"width":0.019946808,"height":0.11412609},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Conversation (8)","depth":16,"bounds":{"left":0.44980052,"top":0.1272945,"width":0.054853722,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Conversation","depth":17,"bounds":{"left":0.46210107,"top":0.1368715,"width":0.02825798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"bounds":{"left":0.5003325,"top":0.1368715,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8","depth":18,"bounds":{"left":0.50332445,"top":0.1368715,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"bounds":{"left":0.5063165,"top":0.1368715,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Commits (35)","depth":16,"bounds":{"left":0.5046542,"top":0.1272945,"width":0.048204787,"height":0.031923383},"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,"bounds":{"left":0.5169548,"top":0.1368715,"width":0.019115692,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"bounds":{"left":0.54853725,"top":0.1368715,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"35","depth":18,"bounds":{"left":0.5515292,"top":0.1368715,"width":0.0056515955,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"bounds":{"left":0.5571808,"top":0.1368715,"width":0.0018284575,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Checks (3)","depth":16,"bounds":{"left":0.55285907,"top":0.1272945,"width":0.042386968,"height":0.031923383},"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,"bounds":{"left":0.56515956,"top":0.1368715,"width":0.015957447,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"bounds":{"left":0.5909242,"top":0.1368715,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3","depth":18,"bounds":{"left":0.59391624,"top":0.1368715,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"bounds":{"left":0.5969083,"top":0.1368715,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Files changed (12)","depth":16,"bounds":{"left":0.595246,"top":0.1272945,"width":0.058344416,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Files changed","depth":17,"bounds":{"left":0.60754657,"top":0.1368715,"width":0.029920213,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"bounds":{"left":0.6492686,"top":0.1368715,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12","depth":18,"bounds":{"left":0.65226066,"top":0.1368715,"width":0.0048204786,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"bounds":{"left":0.6570811,"top":0.1368715,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Pull Request Toolbar","depth":14,"bounds":{"left":0.44980052,"top":0.18236233,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull Request Toolbar","depth":15,"bounds":{"left":0.44980052,"top":0.18515563,"width":0.030086435,"height":0.08060654},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse file tree","depth":14,"bounds":{"left":0.44980052,"top":0.17158818,"width":0.00930851,"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":"AXButton","text":"All commits","depth":14,"bounds":{"left":0.46176863,"top":0.17158818,"width":0.040392287,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All commits","depth":16,"bounds":{"left":0.4714096,"top":0.17677574,"width":0.02244016,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0 of 12 files viewed","depth":15,"bounds":{"left":0.86319816,"top":0.1839585,"width":0.014960106,"height":0.08060654},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Submit review","depth":14,"bounds":{"left":0.9027593,"top":0.17158818,"width":0.03856383,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Submit","depth":16,"bounds":{"left":0.90575135,"top":0.17677574,"width":0.014793883,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"review","depth":16,"bounds":{"left":0.9205452,"top":0.17677574,"width":0.012466756,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Open diff view settings","depth":14,"bounds":{"left":0.9439827,"top":0.17158818,"width":0.00930851,"height":0.022346368},"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 overview panel","depth":14,"bounds":{"left":0.9616024,"top":0.17158818,"width":0.00930851,"height":0.022346368},"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":"Open comments panel","depth":14,"bounds":{"left":0.9722407,"top":0.17158818,"width":0.017287234,"height":0.022346368},"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":"(","depth":16,"bounds":{"left":0.98055184,"top":0.17677574,"width":0.0026595744,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":16,"bounds":{"left":0.98321146,"top":0.17677574,"width":0.0026595744,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":16,"bounds":{"left":0.985871,"top":0.17677574,"width":0.0014960107,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Filter files…","depth":16,"bounds":{"left":0.46110374,"top":0.22067039,"width":0.06815159,"height":0.023942538},"on_screen":true,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Filter options","depth":16,"bounds":{"left":0.53224736,"top":0.21987231,"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":"AXHeading","text":"File tree","depth":15,"bounds":{"left":0.45013297,"top":0.25818038,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"File tree","depth":16,"bounds":{"left":0.45013297,"top":0.26097366,"width":0.014295213,"height":0.0518755},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app","depth":19,"bounds":{"left":0.4660904,"top":0.264166,"width":0.008144947,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Component","depth":21,"bounds":{"left":0.46875,"top":0.29010376,"width":0.025099734,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ElasticSearch/Contract","depth":23,"bounds":{"left":0.4714096,"top":0.31564245,"width":0.049035903,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Searchable.php","depth":25,"bounds":{"left":0.47406915,"top":0.34118116,"width":0.03357713,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Searchable.php","depth":26,"bounds":{"left":0.47406915,"top":0.34118116,"width":0.03357713,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ES","depth":23,"bounds":{"left":0.4714096,"top":0.36671987,"width":0.0056515955,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Processor","depth":25,"bounds":{"left":0.47406915,"top":0.3926576,"width":0.021609042,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Actions","depth":27,"bounds":{"left":0.47672874,"top":0.41819632,"width":0.016123671,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LoadDocumentsAction.php","depth":29,"bounds":{"left":0.4793883,"top":0.4441341,"width":0.05817819,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Traits","depth":27,"bounds":{"left":0.47672874,"top":0.4696728,"width":0.011968086,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SkipActivityTrait.php","depth":29,"bounds":{"left":0.4793883,"top":0.49521148,"width":0.044049203,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"EntityQueryBuilder.php","depth":27,"bounds":{"left":0.47672874,"top":0.5207502,"width":0.049700797,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"EntityQueryBuilder.php","depth":28,"bounds":{"left":0.47672874,"top":0.5207502,"width":0.049700797,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repositories","depth":25,"bounds":{"left":0.47406915,"top":0.5462889,"width":0.026595745,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"EsResetActivityRepository.php","depth":27,"bounds":{"left":0.47672874,"top":0.57222664,"width":0.06549202,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"EsResetActivityRepository.php","depth":28,"bounds":{"left":0.47672874,"top":0.57222664,"width":0.06549202,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ElasticSearchDocumentPartialUpdater.php","depth":25,"bounds":{"left":0.47406915,"top":0.5977654,"width":0.09142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ElasticSearchDocumentPartialUpdater.php","depth":26,"bounds":{"left":0.47406915,"top":0.5977654,"width":0.09142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Console/Commands/Elasticsearch","depth":21,"bounds":{"left":0.46875,"top":0.62330407,"width":0.072972074,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"AsyncUpdateEsActivities.php","depth":23,"bounds":{"left":0.4714096,"top":0.64884275,"width":0.06299867,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"AsyncUpdateEsActivities.php","depth":24,"bounds":{"left":0.4714096,"top":0.64884275,"width":0.06299867,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"AsyncUpdateEsEntities.php","depth":23,"bounds":{"left":0.4714096,"top":0.6743815,"width":0.059341755,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"AsyncUpdateEsEntities.php","depth":24,"bounds":{"left":0.4714096,"top":0.6743815,"width":0.059341755,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Models/ElasticSearch","depth":21,"bounds":{"left":0.46875,"top":0.6999202,"width":0.046043884,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"OpportunityElasticSearchTrait.php","depth":23,"bounds":{"left":0.4714096,"top":0.7258579,"width":0.07347074,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"OpportunityElasticSearchTrait.php","depth":24,"bounds":{"left":0.4714096,"top":0.7258579,"width":0.07347074,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"tests/Unit/Component/ES/Processor","depth":19,"bounds":{"left":0.4660904,"top":0.75139666,"width":0.07712766,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Actions","depth":21,"bounds":{"left":0.46875,"top":0.77693534,"width":0.016123671,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LoadDocumentsActionTest.php","depth":23,"bounds":{"left":0.4714096,"top":0.8024741,"width":0.06698803,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LoadDocumentsActionTest.php","depth":24,"bounds":{"left":0.4714096,"top":0.8024741,"width":0.06698803,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Traits","depth":21,"bounds":{"left":0.46875,"top":0.82801276,"width":0.011968086,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SkipActivityTraitTest.php","depth":23,"bounds":{"left":0.4714096,"top":0.8539505,"width":0.05285904,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SkipActivityTraitTest.php","depth":24,"bounds":{"left":0.4714096,"top":0.8539505,"width":0.05285904,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"EntityQueryBuilderTest.php","depth":21,"bounds":{"left":0.46875,"top":0.87948924,"width":0.05867686,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"EntityQueryBuilderTest.php","depth":22,"bounds":{"left":0.46875,"top":0.87948924,"width":0.05867686,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse file","depth":14,"bounds":{"left":0.5568484,"top":0.2254589,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"app/Component/ElasticSearch/Contract/Searchable.php","depth":15,"bounds":{"left":0.5674867,"top":0.22825219,"width":0.122340426,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"app/Component/ElasticSearch/Contract/Searchable.php","depth":16,"bounds":{"left":0.5674867,"top":0.22984837,"width":0.122340426,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app/Component/ElasticSearch/Contract/Searchable.php","depth":18,"bounds":{"left":0.5674867,"top":0.23184358,"width":0.122340426,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy file name to clipboard","depth":15,"bounds":{"left":0.6924867,"top":0.2254589,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Expand all lines: app/Component/ElasticSearch/Contract/Searchable.php","depth":15,"bounds":{"left":0.7017952,"top":0.2254589,"width":0.00930851,"height":0.022346368},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lines changed: 4 additions & 0 deletions","depth":15,"bounds":{"left":0.91173536,"top":0.23782921,"width":0.019946808,"height":0.11412609},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Not Viewed","depth":14,"bounds":{"left":0.936004,"top":0.2254589,"width":0.026595745,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Viewed","depth":16,"bounds":{"left":0.945645,"top":0.23064645,"width":0.013962766,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Comment on this file","depth":14,"bounds":{"left":0.9652593,"top":0.2254589,"width":0.00930851,"height":0.022346368},"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":"More options","depth":14,"bounds":{"left":0.9772274,"top":0.2254589,"width":0.00930851,"height":0.022346368},"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":"Original file line number","depth":17,"bounds":{"left":0.55418885,"top":0.254988,"width":0.017952127,"height":0.04708699},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Original file line","depth":17,"bounds":{"left":0.57214093,"top":0.26336792,"width":0.018118352,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Diff line number","depth":17,"bounds":{"left":0.5902593,"top":0.254988,"width":0.01761968,"height":0.04708699},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Diff line change","depth":17,"bounds":{"left":0.607879,"top":0.254988,"width":0.016954787,"height":0.04708699},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"@@ -18,4 +18,8 @@ public function getIndex(): string;","depth":18,"bounds":{"left":0.57546544,"top":0.25698325,"width":0.1271609,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"18","depth":16,"bounds":{"left":0.55851066,"top":0.27613726,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"public","depth":18,"bounds":{"left":0.5851064,"top":0.27613726,"width":0.014295213,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":18,"bounds":{"left":0.601895,"top":0.27613726,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"getSearchKey","depth":18,"bounds":{"left":0.623504,"top":0.27613726,"width":0.028756648,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"():","depth":18,"bounds":{"left":0.65226066,"top":0.27613726,"width":0.009640957,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"int","depth":18,"bounds":{"left":0.6619016,"top":0.27613726,"width":0.0071476065,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":18,"bounds":{"left":0.6690492,"top":0.27613726,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"18","depth":16,"bounds":{"left":0.7759308,"top":0.27613726,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"public","depth":18,"bounds":{"left":0.8025266,"top":0.27613726,"width":0.014461436,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":18,"bounds":{"left":0.81931514,"top":0.27613726,"width":0.019281914,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"getSearchKey","depth":18,"bounds":{"left":0.8409242,"top":0.27613726,"width":0.028756648,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"():","depth":18,"bounds":{"left":0.8696808,"top":0.27613726,"width":0.009640957,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"int","depth":18,"bounds":{"left":0.8793218,"top":0.27613726,"width":0.0071476065,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":18,"bounds":{"left":0.8864694,"top":0.27613726,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19","depth":16,"bounds":{"left":0.55851066,"top":0.2952913,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19","depth":16,"bounds":{"left":0.7759308,"top":0.2952913,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20","depth":16,"bounds":{"left":0.55851066,"top":0.31444532,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"public","depth":18,"bounds":{"left":0.5851064,"top":0.31444532,"width":0.014295213,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":18,"bounds":{"left":0.601895,"top":0.31444532,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"getIndexableAttributes","depth":18,"bounds":{"left":0.623504,"top":0.31444532,"width":0.05269282,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"():","depth":18,"bounds":{"left":0.6761968,"top":0.31444532,"width":0.009640957,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"array","depth":18,"bounds":{"left":0.68583775,"top":0.31444532,"width":0.011968086,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":18,"bounds":{"left":0.6978058,"top":0.31444532,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20","depth":16,"bounds":{"left":0.7759308,"top":0.31444532,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"public","depth":18,"bounds":{"left":0.8025266,"top":0.31444532,"width":0.014461436,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":18,"bounds":{"left":0.81931514,"top":0.31444532,"width":0.019281914,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"getIndexableAttributes","depth":18,"bounds":{"left":0.8409242,"top":0.31444532,"width":0.05285904,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"():","depth":18,"bounds":{"left":0.8937833,"top":0.31444532,"width":0.009474734,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"array","depth":18,"bounds":{"left":0.90325797,"top":0.31444532,"width":0.012134309,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":18,"bounds":{"left":0.9153923,"top":0.31444532,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21","depth":16,"bounds":{"left":0.7759308,"top":0.33359936,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"+","depth":18,"bounds":{"left":0.7877327,"top":0.33359936,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22","depth":16,"bounds":{"left":0.7759308,"top":0.3527534,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"+","depth":18,"bounds":{"left":0.7877327,"top":0.3527534,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"public","depth":18,"bounds":{"left":0.8025266,"top":0.3527534,"width":0.014461436,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":18,"bounds":{"left":0.81931514,"top":0.3527534,"width":0.019281914,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"isDeleted","depth":18,"bounds":{"left":0.8409242,"top":0.3527534,"width":0.021609042,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"():","depth":18,"bounds":{"left":0.8625333,"top":0.3527534,"width":0.009640957,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"bool","depth":18,"bounds":{"left":0.8721742,"top":0.3527534,"width":0.009640957,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":18,"bounds":{"left":0.88181514,"top":0.3527534,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"23","depth":16,"bounds":{"left":0.7759308,"top":0.3719074,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"+","depth":18,"bounds":{"left":0.7877327,"top":0.3719074,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"24","depth":16,"bounds":{"left":0.7759308,"top":0.39106146,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"+","depth":18,"bounds":{"left":0.7877327,"top":0.39106146,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"public","depth":18,"bounds":{"left":0.8025266,"top":0.39106146,"width":0.014461436,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":18,"bounds":{"left":0.81931514,"top":0.39106146,"width":0.019281914,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"setRelations","depth":18,"bounds":{"left":0.8409242,"top":0.39106146,"width":0.028756648,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"bounds":{"left":0.8696808,"top":0.39106146,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"array","depth":18,"bounds":{"left":0.8721742,"top":0.39106146,"width":0.011968086,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":18,"bounds":{"left":0.8864694,"top":0.39106146,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"relations","depth":18,"bounds":{"left":0.88896275,"top":0.39106146,"width":0.021609042,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":");","depth":18,"bounds":{"left":0.9105718,"top":0.39106146,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21","depth":16,"bounds":{"left":0.55851066,"top":0.4102155,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"}","depth":18,"bounds":{"left":0.57546544,"top":0.4102155,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"25","depth":16,"bounds":{"left":0.7759308,"top":0.4102155,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"}","depth":18,"bounds":{"left":0.79305184,"top":0.4102155,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Original file line number","depth":16,"bounds":{"left":0.55418885,"top":0.254988,"width":0.017952127,"height":0.04708699},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"@@ -18,4 +18,8 @@ public function getIndex(): string;","depth":18,"bounds":{"left":0.57546544,"top":0.25698325,"width":0.1271609,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"18","depth":16,"bounds":{"left":0.55851066,"top":0.27613726,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19","depth":16,"bounds":{"left":0.55851066,"top":0.2952913,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20","depth":16,"bounds":{"left":0.55851066,"top":0.31444532,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21","depth":16,"bounds":{"left":0.55851066,"top":0.4102155,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Original file line","depth":16,"bounds":{"left":0.57214093,"top":0.26336792,"width":0.018118352,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"@@ -18,4 +18,8 @@ public function getIndex(): string;","depth":18,"bounds":{"left":0.57546544,"top":0.25698325,"width":0.1271609,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"public","depth":18,"bounds":{"left":0.5851064,"top":0.27613726,"width":0.014295213,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":18,"bounds":{"left":0.601895,"top":0.27613726,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"getSearchKey","depth":18,"bounds":{"left":0.623504,"top":0.27613726,"width":0.028756648,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"():","depth":18,"bounds":{"left":0.65226066,"top":0.27613726,"width":0.009640957,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"int","depth":18,"bounds":{"left":0.6619016,"top":0.27613726,"width":0.0071476065,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":18,"bounds":{"left":0.6690492,"top":0.27613726,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"public","depth":18,"bounds":{"left":0.5851064,"top":0.31444532,"width":0.014295213,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":18,"bounds":{"left":0.601895,"top":0.31444532,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"getIndexableAttributes","depth":18,"bounds":{"left":0.623504,"top":0.31444532,"width":0.05269282,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"():","depth":18,"bounds":{"left":0.6761968,"top":0.31444532,"width":0.009640957,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"array","depth":18,"bounds":{"left":0.68583775,"top":0.31444532,"width":0.011968086,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":18,"bounds":{"left":0.6978058,"top":0.31444532,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"}","depth":18,"bounds":{"left":0.57546544,"top":0.4102155,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Diff line number","depth":16,"bounds":{"left":0.5902593,"top":0.254988,"width":0.01761968,"height":0.04708699},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"@@ -18,4 +18,8 @@ public function getIndex(): string;","depth":18,"bounds":{"left":0.57546544,"top":0.25698325,"width":0.1271609,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"18","depth":16,"bounds":{"left":0.7759308,"top":0.27613726,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19","depth":16,"bounds":{"left":0.7759308,"top":0.2952913,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20","depth":16,"bounds":{"left":0.7759308,"top":0.31444532,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21","depth":16,"bounds":{"left":0.7759308,"top":0.33359936,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22","depth":16,"bounds":{"left":0.7759308,"top":0.3527534,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"23","depth":16,"bounds":{"left":0.7759308,"top":0.3719074,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"24","depth":16,"bounds":{"left":0.7759308,"top":0.39106146,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"25","depth":16,"bounds":{"left":0.7759308,"top":0.4102155,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Diff line change","depth":16,"bounds":{"left":0.607879,"top":0.254988,"width":0.016954787,"height":0.04708699},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"@@ -18,4 +18,8 @@ public function getIndex(): string;","depth":18,"bounds":{"left":0.57546544,"top":0.25698325,"width":0.1271609,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"public","depth":18,"bounds":{"left":0.8025266,"top":0.27613726,"width":0.014461436,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":18,"bounds":{"left":0.81931514,"top":0.27613726,"width":0.019281914,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"getSearchKey","depth":18,"bounds":{"left":0.8409242,"top":0.27613726,"width":0.028756648,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"():","depth":18,"bounds":{"left":0.8696808,"top":0.27613726,"width":0.009640957,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"int","depth":18,"bounds":{"left":0.8793218,"top":0.27613726,"width":0.0071476065,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":18,"bounds":{"left":0.8864694,"top":0.27613726,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"public","depth":18,"bounds":{"left":0.8025266,"top":0.31444532,"width":0.014461436,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":18,"bounds":{"left":0.81931514,"top":0.31444532,"width":0.019281914,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"getIndexableAttributes","depth":18,"bounds":{"left":0.8409242,"top":0.31444532,"width":0.05285904,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"():","depth":18,"bounds":{"left":0.8937833,"top":0.31444532,"width":0.009474734,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"array","depth":18,"bounds":{"left":0.90325797,"top":0.31444532,"width":0.012134309,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":18,"bounds":{"left":0.9153923,"top":0.31444532,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"+","depth":18,"bounds":{"left":0.7877327,"top":0.33359936,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"+","depth":18,"bounds":{"left":0.7877327,"top":0.3527534,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"public","depth":18,"bounds":{"left":0.8025266,"top":0.3527534,"width":0.014461436,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":18,"bounds":{"left":0.81931514,"top":0.3527534,"width":0.019281914,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"isDeleted","depth":18,"bounds":{"left":0.8409242,"top":0.3527534,"width":0.021609042,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"():","depth":18,"bounds":{"left":0.8625333,"top":0.3527534,"width":0.009640957,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"bool","depth":18,"bounds":{"left":0.8721742,"top":0.3527534,"width":0.009640957,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":18,"bounds":{"left":0.88181514,"top":0.3527534,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"+","depth":18,"bounds":{"left":0.7877327,"top":0.3719074,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"+","depth":18,"bounds":{"left":0.7877327,"top":0.39106146,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"public","depth":18,"bounds":{"left":0.8025266,"top":0.39106146,"width":0.014461436,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":18,"bounds":{"left":0.81931514,"top":0.39106146,"width":0.019281914,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"setRelations","depth":18,"bounds":{"left":0.8409242,"top":0.39106146,"width":0.028756648,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"bounds":{"left":0.8696808,"top":0.39106146,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"array","depth":18,"bounds":{"left":0.8721742,"top":0.39106146,"width":0.011968086,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":18,"bounds":{"left":0.8864694,"top":0.39106146,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"relations","depth":18,"bounds":{"left":0.88896275,"top":0.39106146,"width":0.021609042,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":");","depth":18,"bounds":{"left":0.9105718,"top":0.39106146,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"}","depth":18,"bounds":{"left":0.79305184,"top":0.4102155,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse file","depth":14,"bounds":{"left":0.5568484,"top":0.44493216,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"app/Component/ES/Processor/Actions/LoadDocumentsAction.php","depth":15,"bounds":{"left":0.5674867,"top":0.44772545,"width":0.13912898,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"app/Component/ES/Processor/Actions/LoadDocumentsAction.php","depth":16,"bounds":{"left":0.5674867,"top":0.44932163,"width":0.13912898,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app/Component/ES/Processor/Actions/LoadDocumentsAction.php","depth":18,"bounds":{"left":0.5674867,"top":0.45131683,"width":0.13912898,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy file name to clipboard","depth":15,"bounds":{"left":0.70927525,"top":0.44493216,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Expand all lines: app/Component/ES/Processor/Actions/LoadDocumentsAction.php","depth":15,"bounds":{"left":0.71858376,"top":0.44493216,"width":0.00930851,"height":0.022346368},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lines changed: 39 additions & 44 deletions","depth":15,"bounds":{"left":0.90043217,"top":0.45730248,"width":0.019946808,"height":0.11412609},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Not Viewed","depth":14,"bounds":{"left":0.936004,"top":0.44493216,"width":0.026595745,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Viewed","depth":16,"bounds":{"left":0.945645,"top":0.4501197,"width":0.013962766,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Comment on this file","depth":14,"bounds":{"left":0.9652593,"top":0.44493216,"width":0.00930851,"height":0.022346368},"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":"More options","depth":14,"bounds":{"left":0.9772274,"top":0.44493216,"width":0.00930851,"height":0.022346368},"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":"Original file line number","depth":17,"bounds":{"left":0.55418885,"top":0.4744613,"width":0.017952127,"height":0.04708699},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Original file line","depth":17,"bounds":{"left":0.57214093,"top":0.4828412,"width":0.018118352,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Diff line number","depth":17,"bounds":{"left":0.5902593,"top":0.4744613,"width":0.01761968,"height":0.04708699},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Diff line change","depth":17,"bounds":{"left":0.607879,"top":0.4744613,"width":0.016954787,"height":0.04708699},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"@@ -5,69 +5,64 @@","depth":18,"bounds":{"left":0.57546544,"top":0.4764565,"width":0.040724736,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5","depth":16,"bounds":{"left":0.5596742,"top":0.49561054,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"namespace","depth":18,"bounds":{"left":0.57546544,"top":0.49561054,"width":0.021609042,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny","depth":18,"bounds":{"left":0.5994016,"top":0.49561054,"width":0.016788565,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.61619014,"top":0.49561054,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Component","depth":18,"bounds":{"left":0.6186835,"top":0.49561054,"width":0.021609042,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.6402925,"top":0.49561054,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ES","depth":18,"bounds":{"left":0.64261967,"top":0.49561054,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.64744014,"top":0.49561054,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Processor","depth":18,"bounds":{"left":0.6497673,"top":0.49561054,"width":0.021609042,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.67137635,"top":0.49561054,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Actions","depth":18,"bounds":{"left":0.67386967,"top":0.49561054,"width":0.016788565,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":18,"bounds":{"left":0.6906583,"top":0.49561054,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5","depth":16,"bounds":{"left":0.7770944,"top":0.49561054,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"namespace","depth":18,"bounds":{"left":0.79305184,"top":0.49561054,"width":0.02144282,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny","depth":18,"bounds":{"left":0.81698805,"top":0.49561054,"width":0.016788565,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.8337766,"top":0.49561054,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Component","depth":18,"bounds":{"left":0.83610374,"top":0.49561054,"width":0.021609042,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.85771275,"top":0.49561054,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ES","depth":18,"bounds":{"left":0.8602061,"top":0.49561054,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.8650266,"top":0.49561054,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Processor","depth":18,"bounds":{"left":0.86735374,"top":0.49561054,"width":0.021609042,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.88896275,"top":0.49561054,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Actions","depth":18,"bounds":{"left":0.8912899,"top":0.49561054,"width":0.016788565,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":18,"bounds":{"left":0.90807843,"top":0.49561054,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6","depth":16,"bounds":{"left":0.5596742,"top":0.51476455,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6","depth":16,"bounds":{"left":0.7770944,"top":0.51476455,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7","depth":16,"bounds":{"left":0.5596742,"top":0.5339186,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"use","depth":18,"bounds":{"left":0.57546544,"top":0.5339186,"width":0.0071476065,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Elastica","depth":18,"bounds":{"left":0.5851064,"top":0.5339186,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.60422206,"top":0.5339186,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Document","depth":18,"bounds":{"left":0.60671544,"top":0.5339186,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":18,"bounds":{"left":0.6258311,"top":0.5339186,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7","depth":16,"bounds":{"left":0.7770944,"top":0.5339186,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"use","depth":18,"bounds":{"left":0.79305184,"top":0.5339186,"width":0.0071476065,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Elastica","depth":18,"bounds":{"left":0.8025266,"top":0.5339186,"width":0.019281914,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.8218085,"top":0.5339186,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Document","depth":18,"bounds":{"left":0.82413566,"top":0.5339186,"width":0.019281914,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":18,"bounds":{"left":0.8434175,"top":0.5339186,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8","depth":16,"bounds":{"left":0.5596742,"top":0.55307263,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":18,"bounds":{"left":0.57014626,"top":0.55307263,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"use","depth":18,"bounds":{"left":0.57546544,"top":0.55307263,"width":0.0071476065,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate","depth":18,"bounds":{"left":0.5851064,"top":0.55307263,"width":0.023936171,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.6090425,"top":0.55307263,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Support","depth":18,"bounds":{"left":0.6115359,"top":0.55307263,"width":0.016788565,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.62832445,"top":0.55307263,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Collection","depth":18,"bounds":{"left":0.6306516,"top":0.55307263,"width":0.023936171,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":18,"bounds":{"left":0.65458775,"top":0.55307263,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9","depth":16,"bounds":{"left":0.5596742,"top":0.57222664,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"use","depth":18,"bounds":{"left":0.57546544,"top":0.57222664,"width":0.0071476065,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny","depth":18,"bounds":{"left":0.5851064,"top":0.57222664,"width":0.016788565,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.601895,"top":0.57222664,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Component","depth":18,"bounds":{"left":0.60422206,"top":0.57222664,"width":0.021609042,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.6258311,"top":0.57222664,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ElasticSearch","depth":18,"bounds":{"left":0.62832445,"top":0.57222664,"width":0.031083776,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.6594083,"top":0.57222664,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Contract","depth":18,"bounds":{"left":0.6619016,"top":0.57222664,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.6810173,"top":0.57222664,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Searchable","depth":18,"bounds":{"left":0.68351066,"top":0.57222664,"width":0.023936171,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":18,"bounds":{"left":0.7074468,"top":0.57222664,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8","depth":16,"bounds":{"left":0.7770944,"top":0.57222664,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"use","depth":18,"bounds":{"left":0.79305184,"top":0.57222664,"width":0.0071476065,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny","depth":18,"bounds":{"left":0.8025266,"top":0.57222664,"width":0.016788565,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.81931514,"top":0.57222664,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Component","depth":18,"bounds":{"left":0.8218085,"top":0.57222664,"width":0.021609042,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.8434175,"top":0.57222664,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ElasticSearch","depth":18,"bounds":{"left":0.84574467,"top":0.57222664,"width":0.03125,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.87699467,"top":0.57222664,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Contract","depth":18,"bounds":{"left":0.8793218,"top":0.57222664,"width":0.019281914,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.89860374,"top":0.57222664,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Searchable","depth":18,"bounds":{"left":0.9009308,"top":0.57222664,"width":0.023936171,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":18,"bounds":{"left":0.92486703,"top":0.57222664,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10","depth":16,"bounds":{"left":0.55851066,"top":0.5913807,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"use","depth":18,"bounds":{"left":0.57546544,"top":0.5913807,"width":0.0071476065,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny","depth":18,"bounds":{"left":0.5851064,"top":0.5913807,"width":0.016788565,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\\","depth":18,"bounds":{"left":0.601895,"top":0.5913807,"width":0.0023271276,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8278037156898686080
|
-3385467385444272894
|
idle
|
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
Unnamed Group
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST [URL_WITH_CREDENTIALS] -18,4 +18,8 @@ public function getIndex(): string;
18
public
function
getSearchKey
():
int
;
18
public
function
getSearchKey
():
int
;
19
19
20
public
function
getIndexableAttributes
():
array
;
20
public
function
getIndexableAttributes
():
array
;
21
+
22
+
public
function
isDeleted
():
bool
;
23
+
24
+
public
function
setRelations
(
array
$
relations
);
21
}
25
}
Original file line number
@@ -18,4 +18,8 @@ public function getIndex(): string;
18
19
20
21
Original file line
@@ -18,4 +18,8 @@ public function getIndex(): string;
public
function
getSearchKey
():
int
;
public
function
getIndexableAttributes
():
array
;
}
Diff line number
@@ -18,4 +18,8 @@ public function getIndex(): string;
18
19
20
21
22
23
24
25
Diff line change
@@ -18,4 +18,8 @@ public function getIndex(): string;
public
function
getSearchKey
():
int
;
public
function
getIndexableAttributes
():
array
;
+
+
public
function
isDeleted
():
bool
;
+
+
public
function
setRelations
(
array
$
relations
);
}
Collapse file
app/Component/ES/Processor/Actions/LoadDocumentsAction.php
app/Component/ES/Processor/Actions/LoadDocumentsAction.php
app/Component/ES/Processor/Actions/LoadDocumentsAction.php
Copy file name to clipboard
Expand all lines: app/Component/ES/Processor/Actions/LoadDocumentsAction.php
Lines changed: 39 additions & 44 deletions
Not Viewed
Viewed
Comment on this file
More options
Original file line number
Original file line
Diff line number
Diff line change
@@ -5,69 +5,64 @@
5
namespace
Jiminny
\
Component
\
ES
\
Processor
\
Actions
;
5
namespace
Jiminny
\
Component
\
ES
\
Processor
\
Actions
;
6
6
7
use
Elastica
\
Document
;
7
use
Elastica
\
Document
;
8
-
use
Illuminate
\
Support
\
Collection
;
9
use
Jiminny
\
Component
\
ElasticSearch
\
Contract
\
Searchable
;
8
use
Jiminny
\
Component
\
ElasticSearch
\
Contract
\
Searchable
;
10
use
Jiminny
\...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
12299
|
546
|
14
|
2026-05-09T08:46:01.287340+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778316361287_m2.jpg...
|
Firefox
|
Personal — Mozilla Firefox
|
True
|
NULL
|
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
Was the assassination attempt on Trump at the correspondence dinner tonight staged or real? - [EMAIL] - Gmail
Was the assassination attempt on Trump at the correspondence dinner tonight staged or real? - [EMAIL] - Gmail
(25) Quora
(25) Quora
New Tab
New Tab
Close tab
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
22°
C
New York City
Open menu
Mozilla Firefox
Search with Google or enter address
Search with Google or enter address
Inbox (63) - [EMAIL] - Gmail
Inbox (63) - [EMAIL] - Gmail
Open context menu for Inbox (63) - [EMAIL] - Gmail
(137) YouTube
(137) YouTube
Open context menu for (137) YouTube
Screenpipe — Archive
Screenpipe — Archive
Open context menu for Screenpipe — Archive
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
Open context menu for screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
Screenpipe — Archive
Screenpipe — Archive
Open context menu for Screenpipe — Archive
Denník N - Nezávislý denník
Denník N - Nezávislý denník
Open context menu for Denník N - Nezávislý denník
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Open context menu for DXP4800PLUS-B5F8
(58) Inbox | [EMAIL] | Proton Mail
(58) Inbox | [EMAIL] | Proton Mail
Open context menu for (58) Inbox | [EMAIL] | Proton Mail
Customize
Customize
http://[IP_ADDRESS]:8766...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Pull requests · screenpipe/screenpipe · GitHub","depth":4,"bounds":{"left":0.3307846,"top":0.08140463,"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.34408244,"top":0.092577815,"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.3307846,"top":0.11412609,"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.34408244,"top":0.12529927,"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.3307846,"top":0.14684756,"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.34408244,"top":0.15802075,"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.3307846,"top":0.17956904,"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.34408244,"top":0.19074222,"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.3307846,"top":0.2122905,"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.34408244,"top":0.22346368,"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.3307846,"top":0.24501197,"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.34408244,"top":0.25618514,"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.3307846,"top":0.27773345,"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.34408244,"top":0.28890663,"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.3307846,"top":0.3104549,"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.34408244,"top":0.3216281,"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.3307846,"top":0.34317636,"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.34408244,"top":0.35434955,"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.3307846,"top":0.37589785,"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.34408244,"top":0.38707104,"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.3307846,"top":0.4086193,"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.34408244,"top":0.4197925,"width":0.030086435,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Was the assassination attempt on Trump at the correspondence dinner tonight staged or real? - kovaliklukas@gmail.com - Gmail","depth":4,"bounds":{"left":0.3307846,"top":0.44134077,"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":"Was the assassination attempt on Trump at the correspondence dinner tonight staged or real? - kovaliklukas@gmail.com - Gmail","depth":5,"bounds":{"left":0.34408244,"top":0.45251396,"width":0.22323804,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"(25) Quora","depth":4,"bounds":{"left":0.3307846,"top":0.47406226,"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.34408244,"top":0.48523542,"width":0.018949468,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.3307846,"top":0.5067837,"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.34408244,"top":0.5179569,"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.43218085,"top":0.5139665,"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":"Location Logger","depth":4,"bounds":{"left":0.3307846,"top":0.5395052,"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.34408244,"top":0.5506784,"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.3307846,"top":0.57222664,"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.34408244,"top":0.58339983,"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.3307846,"top":0.6049481,"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.34408244,"top":0.6161213,"width":0.021609042,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Select: payments - db - Adminer","depth":4,"bounds":{"left":0.3307846,"top":0.63766956,"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":"Select: payments - db - Adminer","depth":5,"bounds":{"left":0.34408244,"top":0.64884275,"width":0.05651596,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":4,"bounds":{"left":0.3307846,"top":0.6703911,"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.34408244,"top":0.6815643,"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.3307846,"top":0.70311254,"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.34408244,"top":0.71428573,"width":0.113696806,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.3336104,"top":0.73743016,"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.3336104,"top":0.97725457,"width":0.010638298,"height":0.02274543},"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.34458113,"top":0.97725457,"width":0.010638298,"height":0.02274543},"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.35571808,"top":0.97725457,"width":0.010638298,"height":0.02274543},"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.36685506,"top":0.97725457,"width":0.010638298,"height":0.02274543},"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.37799203,"top":0.97725457,"width":0.010638298,"height":0.02274543},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"22°","depth":8,"bounds":{"left":0.9232048,"top":0.111332804,"width":0.00930851,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"C","depth":8,"bounds":{"left":0.9325133,"top":0.111332804,"width":0.0039893617,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"New York City","depth":8,"bounds":{"left":0.9232048,"top":0.12769353,"width":0.02825798,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Open menu","depth":7,"bounds":{"left":0.95511967,"top":0.105347164,"width":0.01662234,"height":0.043894652},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Mozilla Firefox","depth":8,"bounds":{"left":0.54870343,"top":0.415004,"width":0.3287899,"height":0.051077414},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Search with Google or enter address","depth":8,"bounds":{"left":0.5934175,"top":0.49002394,"width":0.2393617,"height":0.0415004},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search with Google or enter address","depth":10,"bounds":{"left":0.6100399,"top":0.50319237,"width":0.08344415,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Inbox (63) - kovaliklukas@gmail.com - Gmail","depth":11,"bounds":{"left":0.55352396,"top":0.5554669,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Inbox (63) - kovaliklukas@gmail.com - Gmail","depth":13,"bounds":{"left":0.5581782,"top":0.62450117,"width":0.030585106,"height":0.051077414},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Inbox (63) - kovaliklukas@gmail.com - Gmail","depth":11,"bounds":{"left":0.58543885,"top":0.5642458,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"(137) YouTube","depth":11,"bounds":{"left":0.5934175,"top":0.5554669,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"(137) YouTube","depth":13,"bounds":{"left":0.5990692,"top":0.62450117,"width":0.028590426,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for (137) YouTube","depth":11,"bounds":{"left":0.6253325,"top":0.5642458,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Screenpipe — Archive","depth":11,"bounds":{"left":0.63331115,"top":0.5554669,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":13,"bounds":{"left":0.63946146,"top":0.62450117,"width":0.027593086,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Screenpipe — Archive","depth":11,"bounds":{"left":0.66522604,"top":0.5642458,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub","depth":11,"bounds":{"left":0.6732048,"top":0.5554669,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub","depth":13,"bounds":{"left":0.67802525,"top":0.62450117,"width":0.03025266,"height":0.07661612},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub","depth":11,"bounds":{"left":0.70511967,"top":0.5642458,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Screenpipe — Archive","depth":11,"bounds":{"left":0.7130984,"top":0.5554669,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":13,"bounds":{"left":0.71924865,"top":0.62450117,"width":0.027593086,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Screenpipe — Archive","depth":11,"bounds":{"left":0.7450133,"top":0.5642458,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Denník N - Nezávislý denník","depth":11,"bounds":{"left":0.75299203,"top":0.5554669,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Denník N - Nezávislý denník","depth":13,"bounds":{"left":0.7621343,"top":0.62450117,"width":0.021609042,"height":0.03830806},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Denník N - Nezávislý denník","depth":11,"bounds":{"left":0.7849069,"top":0.5642458,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"DXP4800PLUS-B5F8","depth":11,"bounds":{"left":0.79288566,"top":0.5554669,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DXP4800PLUS-B5F8","depth":13,"bounds":{"left":0.7977061,"top":0.62450117,"width":0.03025266,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for DXP4800PLUS-B5F8","depth":11,"bounds":{"left":0.82480055,"top":0.5642458,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"(58) Inbox | kovaliklukas@proton.me | Proton Mail","depth":11,"bounds":{"left":0.8327792,"top":0.5554669,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"(58) Inbox | kovaliklukas@proton.me | Proton Mail","depth":13,"bounds":{"left":0.8374335,"top":0.62450117,"width":0.030585106,"height":0.051077414},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for (58) Inbox | kovaliklukas@proton.me | Proton Mail","depth":11,"bounds":{"left":0.8646942,"top":0.5642458,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Customize","depth":8,"bounds":{"left":0.96127,"top":0.95810056,"width":0.012965426,"height":0.0311253},"on_screen":true,"help_text":"Customize this page","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customize","depth":10,"bounds":{"left":0.9644282,"top":0.96648043,"width":0.024102394,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://100.73.206.126:8766","depth":5,"bounds":{"left":0.44581118,"top":0.9948124,"width":0.04737367,"height":0.005187571},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8277926323075844754
|
-4722713553143847150
|
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
Was the assassination attempt on Trump at the correspondence dinner tonight staged or real? - [EMAIL] - Gmail
Was the assassination attempt on Trump at the correspondence dinner tonight staged or real? - [EMAIL] - Gmail
(25) Quora
(25) Quora
New Tab
New Tab
Close tab
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
22°
C
New York City
Open menu
Mozilla Firefox
Search with Google or enter address
Search with Google or enter address
Inbox (63) - [EMAIL] - Gmail
Inbox (63) - [EMAIL] - Gmail
Open context menu for Inbox (63) - [EMAIL] - Gmail
(137) YouTube
(137) YouTube
Open context menu for (137) YouTube
Screenpipe — Archive
Screenpipe — Archive
Open context menu for Screenpipe — Archive
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
Open context menu for screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
Screenpipe — Archive
Screenpipe — Archive
Open context menu for Screenpipe — Archive
Denník N - Nezávislý denník
Denník N - Nezávislý denník
Open context menu for Denník N - Nezávislý denník
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Open context menu for DXP4800PLUS-B5F8
(58) Inbox | [EMAIL] | Proton Mail
(58) Inbox | [EMAIL] | Proton Mail
Open context menu for (58) Inbox | [EMAIL] | Proton Mail
Customize
Customize
http://[IP_ADDRESS]:8766...
|
12298
|
NULL
|
NULL
|
NULL
|
|
12300
|
545
|
14
|
2026-05-09T08:46:01.370697+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778316361370_m1.jpg...
|
Firefox
|
Personal — Mozilla Firefox
|
True
|
NULL
|
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
Was the assassination attempt on Trump at the correspondence dinner tonight staged or real? - [EMAIL] - Gmail
Was the assassination attempt on Trump at the correspondence dinner tonight staged or real? - [EMAIL] - Gmail
(25) Quora
(25) Quora
New Tab
New Tab
Close tab
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
22°
C
New York City
Open menu
Mozilla Firefox
Search with Google or enter address
Search with Google or enter address
Inbox (63) - [EMAIL] - Gmail
Inbox (63) - [EMAIL] - Gmail
Open context menu for Inbox (63) - [EMAIL] - Gmail
(137) YouTube
(137) YouTube
Open context menu for (137) YouTube
Screenpipe — Archive
Screenpipe — Archive
Open context menu for Screenpipe — Archive
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
Open context menu for screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
Screenpipe — Archive
Screenpipe — Archive
Open context menu for Screenpipe — Archive
Denník N - Nezávislý denník
Denník N - Nezávislý denník
Open context menu for Denník N - Nezávislý denník
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Open context menu for DXP4800PLUS-B5F8
(58) Inbox | [EMAIL] | Proton Mail
(58) Inbox | [EMAIL] | Proton Mail
Open context menu for (58) Inbox | [EMAIL] | Proton Mail
Customize
Customize
http://[IP_ADDRESS]:8766...
|
[{"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":"Was the assassination attempt on Trump at the correspondence dinner tonight staged or real? - 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":"Was the assassination attempt on Trump at the correspondence dinner tonight staged or real? - 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":"New Tab","depth":4,"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,"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":"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":"22°","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"C","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"New York City","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Open menu","depth":7,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Mozilla Firefox","depth":8,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Search with Google or enter address","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search with Google or enter address","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Inbox (63) - kovaliklukas@gmail.com - Gmail","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Inbox (63) - kovaliklukas@gmail.com - Gmail","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Inbox (63) - kovaliklukas@gmail.com - Gmail","depth":11,"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"(137) YouTube","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"(137) YouTube","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for (137) YouTube","depth":11,"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Screenpipe — Archive","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Screenpipe — Archive","depth":11,"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub","depth":11,"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Screenpipe — Archive","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Screenpipe — Archive","depth":11,"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Denník N - Nezávislý denník","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Denník N - Nezávislý denník","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Denník N - Nezávislý denník","depth":11,"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"DXP4800PLUS-B5F8","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DXP4800PLUS-B5F8","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for DXP4800PLUS-B5F8","depth":11,"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"(58) Inbox | kovaliklukas@proton.me | Proton Mail","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"(58) Inbox | kovaliklukas@proton.me | Proton Mail","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for (58) Inbox | kovaliklukas@proton.me | Proton Mail","depth":11,"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Customize","depth":8,"on_screen":true,"help_text":"Customize this page","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customize","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://100.73.206.126:8766","depth":5,"bounds":{"left":0.36666667,"top":0.0,"width":0.098958336,"height":0.015},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8277926323075844754
|
-4722713553143847150
|
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
Was the assassination attempt on Trump at the correspondence dinner tonight staged or real? - [EMAIL] - Gmail
Was the assassination attempt on Trump at the correspondence dinner tonight staged or real? - [EMAIL] - Gmail
(25) Quora
(25) Quora
New Tab
New Tab
Close tab
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
22°
C
New York City
Open menu
Mozilla Firefox
Search with Google or enter address
Search with Google or enter address
Inbox (63) - [EMAIL] - Gmail
Inbox (63) - [EMAIL] - Gmail
Open context menu for Inbox (63) - [EMAIL] - Gmail
(137) YouTube
(137) YouTube
Open context menu for (137) YouTube
Screenpipe — Archive
Screenpipe — Archive
Open context menu for Screenpipe — Archive
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
Open context menu for screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
Screenpipe — Archive
Screenpipe — Archive
Open context menu for Screenpipe — Archive
Denník N - Nezávislý denník
Denník N - Nezávislý denník
Open context menu for Denník N - Nezávislý denník
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Open context menu for DXP4800PLUS-B5F8
(58) Inbox | [EMAIL] | Proton Mail
(58) Inbox | [EMAIL] | Proton Mail
Open context menu for (58) Inbox | [EMAIL] | Proton Mail
Customize
Customize
http://[IP_ADDRESS]:8766...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3220
|
123
|
24
|
2026-05-07T12:07:34.802244+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778155654802_m1.jpg...
|
iTerm2
|
NULL
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
PostmanFileEditViewWindowHelp‹$0lohlSupport Daily PostmanFileEditViewWindowHelp‹$0lohlSupport Daily • now100% <478DEV (docker)DOCKERO ₴1DEV (docker)H82APP (-zsh)-zsh• $4screenpipe"•₴55.95ms DONE-zshThu 7 May 15:07:34T81₴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
|
-8276313581904558713
|
NULL
|
click
|
ocr
|
NULL
|
PostmanFileEditViewWindowHelp‹$0lohlSupport Daily PostmanFileEditViewWindowHelp‹$0lohlSupport Daily • now100% <478DEV (docker)DOCKERO ₴1DEV (docker)H82APP (-zsh)-zsh• $4screenpipe"•₴55.95ms DONE-zshThu 7 May 15:07:34T81₴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...
|
3217
|
NULL
|
NULL
|
NULL
|
|
3430
|
127
|
23
|
2026-05-07T12:19:00.507843+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778156340507_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
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
Close
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.
What "two buckets per request" actually costs
What "two buckets per request" actually costs
Each request makes
one round trip to Redis
— not two — because you fold both bucket checks into a single Lua script that runs atomically server-side:
Copy to clipboard
lua
-- KEYS[1] = burst bucket key (or search)
-- KEYS[2] = daily bucket key
-- ARGV[1] = now (ms) ARGV[2] = window_ms
-- ARGV[3] = bucket_max ARGV[4] = daily_max
-- ARGV[5] = request_id ARGV[6] = daily_ttl
-- Trim sliding window
redis
.
call
(
'ZREMRANGEBYSCORE'
,
KEYS
[
1
]
,
0
,
ARGV
[
1
]
-
ARGV
[
2
]
)
local
burst_used
=
redis
.
call
(
'ZCARD'
,
KEYS
[
1
]
)
local
daily_used
=
tonumber
(
redis
.
call
(
'GET'
,
KEYS
[
2
]
)
or
'0'
)
if
burst_used
>=
tonumber
(
ARGV
[
3
]
)
then
-- Tell caller how long to sleep until oldest entry expires
local
oldest
=
redis
.
call
(
'ZRANGE'
,
KEYS
[
1
]
,
0
,
0
,
'WITHSCORES'
)
return
{
0
,
'BURST'
,
(
oldest
[
2
]
+
ARGV
[
2
]
)
-
ARGV
[
1
]
}
end
if
daily_used
>=
tonumber
(
ARGV
[
4
]
)
then
return
{
0
,
'DAILY'
,
-
1
}
end
redis
.
call
(
'ZADD'
,
KEYS
[
1
]
,
ARGV
[
1
]
,
ARGV
[
5
]
)
redis
.
call
(
'PEXPIRE'
,
KEYS
[
1
]
,
ARGV
[
2
]
+
1000
)
local
d
=
redis
.
call
(
'INCR'
,
KEYS
[
2
]
)
if
d
==
1
then
redis
.
call
(
'EXPIRE'
,
KEYS
[
2
]
,
ARGV
[
6
]
)...
|
[{"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":false,"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":"Open sidebar","depth":14,"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":"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":"AXButton","text":"Definition of incarcerated","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 Definition of incarcerated","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":"Chromecast remote volume buttons not working","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 Chromecast remote volume buttons not working","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":"Salesforce API errors with Organization and FieldDefinition queries","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 Salesforce API errors with Organization and FieldDefinition queries","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":"Daily activity summary from screenpipe data","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 Daily activity summary from screenpipe data","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":"MacBook unexpected restarts and kanji screen","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 MacBook unexpected restarts and kanji screen","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":"Security patch review and testing guidance","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 Security patch review and testing guidance","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":"Food calorie values reference","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 Food calorie values reference","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":"Tracking location history from last week","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 Tracking location history from last week","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,"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,"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":20,"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":22,"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"More options for HubSpot rate limit implementation strategy","depth":20,"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":22,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Share chat","depth":22,"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":22,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"You said: So just a solution for rate limit implementation.","depth":21,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"You said: So just a solution for rate limit implementation.","depth":22,"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":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"updating activity (engagement, meeting, call, note)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"searching for a company or contact","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"updating deal","depth":26,"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":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"where to store it","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"how to read it","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"how to work with multiple jobs","depth":26,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"https://developers.hubspot.com/docs/developer-tooling/platform/usage-guidelines","depth":26,"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":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"). Example of such a error Client error:","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"POST https://api.hubapi.com/crm/v3/objects/contact/search","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"resulted in a","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"429 Too Many Requests","depth":27,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Show more","depth":23,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:42","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Retry","depth":23,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Edit","depth":23,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Copy","depth":23,"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":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Claude responded: Current HubSpot limits (Apr 2026)","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Synthesized HubSpot rate limit architecture with Redis storage and sliding window algorithms","depth":23,"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":24,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Current HubSpot limits (Apr 2026)","depth":25,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Current HubSpot limits (Apr 2026)","depth":26,"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":26,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":". The burst window is per app; the daily quota is per portal.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"hubspot","depth":27,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"hubspot","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"hubspot","depth":27,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"hubspot","depth":28,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":". That's the limit the 429 in your example is hitting (","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"secondly limit","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"on","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/crm/v3/objects/contact/search","depth":27,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"X-HubSpot-RateLimit-*","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"headers","depth":26,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"hubspot","depth":27,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"hubspot","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"hubspot","depth":27,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"hubspot","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Non-search endpoints return","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"X-HubSpot-RateLimit-Remaining","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-Max","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", and","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-Interval-Milliseconds","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":". The daily headers are not returned for OAuth-authenticated calls","depth":26,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— that's enforced for marketplace listing, but it's also a sane operational target.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"hubspot","depth":27,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"hubspot","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"hubspot","depth":27,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"hubspot","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"So you have","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"four buckets","depth":27,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Where to store it","depth":25,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Where to store it","depth":26,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"INCR","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"EXPIRE","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"plus Lua scripting for true CAS semantics.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Key layout I'd use:","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy to clipboard","depth":28,"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":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"hubspot:rl:search:{portalId} ZSET (sliding 1s)","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"hubspot:rl:daily:{portalId} STRING + TTL to midnight TZ","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"hubspot:rl:meta:{portalId} HASH (last seen headers)","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"The two short-window buckets are sliding-window-log (Redis ZSET, score =","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"microtime","depth":27,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"The daily bucket is a plain","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"INCR","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"with TTL set to seconds-until-midnight in","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HubSpot's account timezone","depth":27,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"How to read it","depth":25,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"How to read it","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Two-phase: optimistic pre-check, authoritative post-update.","depth":26,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"After the call, parse","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"X-HubSpot-RateLimit-Remaining","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-Max","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-Interval-Milliseconds","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"and store them in","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"hubspot:rl:meta:{portalId}","depth":27,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"For search specifically, since headers don't come back, the local counter","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"is","depth":27,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"not","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"on 429 (you really did make that request).","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"How to work with multiple jobs","depth":25,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"How to work with multiple jobs","depth":26,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Concurrency cap","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"via","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Queue::throttle()","depth":28,"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":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Per-tenant fairness","depth":28,"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":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Priority lanes","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— webhook-driven updates (user-visible latency) should outrank background batch syncs. Two queues:","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"hubspot-priority","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"and","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"hubspot-bulk","depth":28,"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":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Backoff on 429","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— respect the","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Retry-After","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"header. If absent, exponential with jitter (e.g.,","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"min(2^attempt * 250ms, 30s) ± 20%","depth":28,"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":27,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"How to work with paginated requests","depth":25,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"How to work with paginated requests","depth":26,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Two practical rules:","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Don't hold the worker idle while paginating.","depth":28,"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":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"processing","depth":28,"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":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Always batch where HubSpot offers it.","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"POST /crm/v3/objects/{type}/batch/{read|update|create}","depth":28,"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":27,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Walkthrough: 600 opportunities","depth":25,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Walkthrough: 600 opportunities","depth":26,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sane flow:","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Identify deltas","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— if you can avoid Search at all, do. Use","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"lastmodifieddate","depth":28,"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":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Batch read","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"current state —","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"POST /crm/v3/objects/deals/batch/read","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"with 100 IDs per call → 6 calls. Burst weight 6.","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Compute diff","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"in your code (no API).","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Batch update","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"—","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"POST /crm/v3/objects/deals/batch/update","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"with 100 per call → 6 calls.","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Associations","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"—","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"POST /crm/v4/associations/{from}/{to}/batch/create","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"if needed → another few batch calls.","depth":27,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Recognition: pre-check denies if","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"<weight>","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"slots aren't free; on 429 the response surfaces","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"policyName","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(DAILY/SECONDLY) — log it, push the job back with","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Retry-After","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"delay, increment a metric so you can alarm on sustained 429 rate.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Pitfalls & bottlenecks worth pre-empting","depth":25,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Pitfalls & bottlenecks worth pre-empting","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Daily quota is shared across the whole portal","depth":28,"on_screen":false,"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":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Search is uniquely fragile","depth":28,"on_screen":false,"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":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"hs_object_id","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ranges or by","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"lastmodifieddate","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"windows.","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Retry storms after HubSpot incidents","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— always jitter, always cap total retries (e.g., 5 attempts, then dead-letter).","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Webhook → sync → webhook loops","depth":28,"on_screen":false,"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":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"jy_last_sync_id","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":") and ignore webhooks where it just changed.","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Token refresh","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— OAuth refresh itself counts against burst. Cache the access token in Redis with TTL =","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"expires_in - 60s","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", single-flight the refresh (only one worker refreshes; others wait on a lock).","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Search latency for fresh writes","depth":28,"on_screen":false,"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":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Clock skew","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— Redis is authoritative. Don't use","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"time()","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"from each worker for window scoring; use","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"redis.call('TIME')","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"inside the Lua script.","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dead workers with held tokens","depth":28,"on_screen":false,"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":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"The 5% error rule","depth":28,"on_screen":false,"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":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Phantom contention with Laravel","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RateLimited","depth":29,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"middleware","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":": it's per-job-class by default, not per-portal. If your","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncDealJob","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"and","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UpdateActivityJob","depth":28,"on_screen":false,"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":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HubspotRateLimiter","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"service that everything routes through.","depth":27,"on_screen":false,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy","depth":23,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Give positive feedback","depth":23,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Give negative feedback","depth":23,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Retry","depth":23,"on_screen":false,"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":21,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"You said: What will happen if there are two different types of rate limits?","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"What will happen if there are two different types of rate limits?","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Search requests that have 5 requests per second","depth":26,"on_screen":false,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"13:40","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Retry","depth":23,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Edit","depth":23,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Copy","depth":23,"on_screen":false,"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":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Claude responded: They're independent buckets — with one shared bucket on top.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Analyzed independent rate limit buckets and their practical interactions","depth":23,"on_screen":false,"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":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"They're independent buckets — with one shared bucket on top.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"The three buckets and what each call hits","depth":25,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"The three buckets and what each call hits","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy to clipboard","depth":28,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"┌──────────────────┐","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Search request ──→ │ Search: 5/sec │ ──┐","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"└──────────────────┘ │","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"├──→ ┌─────────────────┐","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"┌──────────────────┐ │ │ Daily: 250k–1M │","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Non-search call ──→ │ Burst: 190/10s │ ──┘ │ (per portal) │","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"└──────────────────┘ └─────────────────┘","depth":28,"on_screen":false,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"What this means practically","depth":25,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"What this means practically","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Hitting search secondly limit (5/s):","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Only further","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/search","depth":27,"on_screen":false,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"lastmodifieddate","depth":27,"on_screen":false,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Hitting burst limit (190/10s):","depth":27,"on_screen":false,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Hitting daily limit:","depth":27,"on_screen":false,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"So can one type of request block the other?","depth":25,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"So can one type of request block the other?","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Search → Burst:","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"No.","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Saturating Search at 50 calls per 10s leaves your full 190/10s burst untouched.","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Burst → Search:","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"No.","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Saturating burst leaves Search's 5/s untouched.","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Either → Daily:","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Yes","depth":28,"on_screen":false,"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":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"In theory you can sustain ~50 search + ~190 other =","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"~240 calls per 10 seconds","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"indefinitely (until daily runs out), because the two buckets bill independently.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Implementation consequence","depth":25,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Implementation consequence","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Your rate limiter needs to know which bucket a request hits before it acquires. Cleanest pattern:","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy to clipboard","depth":28,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"php","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"$limiter","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"->","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"acquire","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"'search'","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"$weight","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":")","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":";","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"// for search endpoints only","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"$limiter","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"->","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"acquire","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"'burst'","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"$weight","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":")","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":";","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"// for everything else","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"$limiter","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"->","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"acquire","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"'daily'","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"$weight","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":")","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":";","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"// every call, both kinds","depth":28,"on_screen":false,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"acquire('search')","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"+","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"acquire('daily')","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":". A batch update calls","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"acquire('burst')","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"+","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"acquire('daily')","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"One subtle pitfall: when you backoff on a 429,","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"inspect","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"policyName","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"in the response body","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"to know which bucket actually fired. If you see","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SECONDLY","depth":27,"on_screen":false,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"The other subtlety: the burst response gives you","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"X-HubSpot-RateLimit-Remaining","depth":27,"on_screen":false,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy","depth":23,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Give positive feedback","depth":23,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Give negative feedback","depth":23,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Retry","depth":23,"on_screen":false,"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":21,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"You said: Ok, so what will happen each time I make a request?","depth":22,"on_screen":false,"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":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"13:44","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Retry","depth":23,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Edit","depth":23,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Copy","depth":23,"on_screen":false,"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":22,"on_screen":false,"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":23,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Analyzed per-request overhead concerns and quantified Redis performance impact","depth":23,"on_screen":false,"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":24,"on_screen":false,"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":26,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"What \"two buckets per request\" actually costs","depth":25,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"What \"two buckets per request\" actually costs","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Each request makes","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"one round trip to Redis","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— not two — because you fold both bucket checks into a single Lua script that runs atomically server-side:","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy to clipboard","depth":28,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"lua","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-- KEYS[1] = burst bucket key (or search)","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-- KEYS[2] = daily bucket key","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-- ARGV[1] = now (ms) ARGV[2] = window_ms","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-- ARGV[3] = bucket_max ARGV[4] = daily_max","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-- ARGV[5] = request_id ARGV[6] = daily_ttl","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-- Trim sliding window","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"redis","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"call","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"'ZREMRANGEBYSCORE'","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KEYS","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"[","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"]","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ARGV","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"[","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"]","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ARGV","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"[","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"]","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":")","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"local","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"burst_used","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"redis","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"call","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"'ZCARD'","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KEYS","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"[","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"]","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":")","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"local","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"daily_used","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"tonumber","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"redis","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"call","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"'GET'","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KEYS","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"[","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"]","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":")","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"or","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"'0'","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":")","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"if","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"burst_used","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":">=","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"tonumber","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ARGV","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"[","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"3","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"]","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":")","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"then","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-- Tell caller how long to sleep until oldest entry expires","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"local","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"oldest","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"redis","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"call","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"'ZRANGE'","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KEYS","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"[","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"]","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"'WITHSCORES'","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":")","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"return","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"{","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"'BURST'","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"oldest","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"[","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"]","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"+","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ARGV","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"[","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"]","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":")","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ARGV","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"[","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"]","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"}","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"end","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"if","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"daily_used","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":">=","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"tonumber","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ARGV","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"[","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"]","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":")","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"then","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"return","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"{","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"'DAILY'","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"}","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"end","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"redis","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"call","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"'ZADD'","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KEYS","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"[","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"]","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ARGV","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"[","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"]","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ARGV","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"[","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"5","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"]","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":")","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"redis","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"call","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"'PEXPIRE'","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KEYS","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"[","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"]","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ARGV","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"[","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"]","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"+","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1000","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":")","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"local","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"d","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"redis","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"call","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"'INCR'","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KEYS","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"[","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"]","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":")","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"if","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"d","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"==","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"then","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"redis","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"call","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"'EXPIRE'","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KEYS","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"[","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"]","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ARGV","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"[","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"6","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"]","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":")","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"on_screen":false,"role_description":"text"}]...
|
-8274446445292519666
|
-8642777718357926828
|
idle
|
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
Close
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.
What "two buckets per request" actually costs
What "two buckets per request" actually costs
Each request makes
one round trip to Redis
— not two — because you fold both bucket checks into a single Lua script that runs atomically server-side:
Copy to clipboard
lua
-- KEYS[1] = burst bucket key (or search)
-- KEYS[2] = daily bucket key
-- ARGV[1] = now (ms) ARGV[2] = window_ms
-- ARGV[3] = bucket_max ARGV[4] = daily_max
-- ARGV[5] = request_id ARGV[6] = daily_ttl
-- Trim sliding window
redis
.
call
(
'ZREMRANGEBYSCORE'
,
KEYS
[
1
]
,
0
,
ARGV
[
1
]
-
ARGV
[
2
]
)
local
burst_used
=
redis
.
call
(
'ZCARD'
,
KEYS
[
1
]
)
local
daily_used
=
tonumber
(
redis
.
call
(
'GET'
,
KEYS
[
2
]
)
or
'0'
)
if
burst_used
>=
tonumber
(
ARGV
[
3
]
)
then
-- Tell caller how long to sleep until oldest entry expires
local
oldest
=
redis
.
call
(
'ZRANGE'
,
KEYS
[
1
]
,
0
,
0
,
'WITHSCORES'
)
return
{
0
,
'BURST'
,
(
oldest
[
2
]
+
ARGV
[
2
]
)
-
ARGV
[
1
]
}
end
if
daily_used
>=
tonumber
(
ARGV
[
4
]
)
then
return
{
0
,
'DAILY'
,
-
1
}
end
redis
.
call
(
'ZADD'
,
KEYS
[
1
]
,
ARGV
[
1
]
,
ARGV
[
5
]
)
redis
.
call
(
'PEXPIRE'
,
KEYS
[
1
]
,
ARGV
[
2
]
+
1000
)
local
d
=
redis
.
call
(
'INCR'
,
KEYS
[
2
]
)
if
d
==
1
then
redis
.
call
(
'EXPIRE'
,
KEYS
[
2
]
,
ARGV
[
6
]
)...
|
3427
|
NULL
|
NULL
|
NULL
|
|
4517
|
165
|
6
|
2026-05-07T14:07:28.226016+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778162848226_m1.jpg...
|
PhpStorm
|
faVsco.js – HS_local [jiminny@localhost]
|
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
Sync Changes
Hide This Notification
Code changed:
Hide
6
1
6
Previous Highlighted Error
Next Highlighted Error
# [PASSWORD_DOTS] HS [PASSWORD_DOTS]
select * from teams where id = 2; # 2
select * from features; # 2
select * from team_features where team_id = 2; # 2
select * from crm_configurations where id = 2; # 2
select * from users where team_id = 2; #
select * from playbooks where team_id = 2; # event 38
select * from playbook_categories where playbook_id = 38; #
SELECT * FROM activities WHERE crm_configuration_id = 2 and crm_provider_id is not null order by id desc;
[URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
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":"master, menu","depth":5,"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,"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":"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":"6","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"6","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":"# **************************** HS **************************************\n\nselect * from teams where id = 2; # 2\nselect * from features; # 2\nselect * from team_features where team_id = 2; # 2\nselect * from crm_configurations where id = 2; # 2\nselect * from users where team_id = 2; #\nselect * from playbooks where team_id = 2; # event 38\nselect * from playbook_categories where playbook_id = 38; #\n\nSELECT * FROM activities WHERE crm_configuration_id = 2 and crm_provider_id is not null order by id desc;\nhttps://app.hubspot.com/contacts/4392066/deal/16964514951/?engagement=96069102624\n https://app.staging.jiminny.com/playback/d5df34dc-bd66-4ff5-a7b3-8d3be30322a0\n\nSELECT * FROM activities WHERE uuid_to_bin('04fdcd0d-818f-4c53-92dc-6f18bc753ffd') = uuid;\n# 609126 softphone tr. 11241\n\nSELECT * FROM activities WHERE uuid_to_bin('6521bfcd-5a30-46e5-9f74-5440fd48befd') = uuid;\n# 608874 conference tr. 11226 crmId: 103422236596\n\nselect * from ai_prompts where transcription_id IN (11241, 11226);\nselect * from activity_summary_logs where activity_id = 608874;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nselect * from crm_field_data where activity_id = 1223;\n\nselect * from crm_layouts where crm_configuration_id = 2;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id IN (554);\nselect * from crm_fields where crm_configuration_id = 11 and object_type = 'event';\nSELECT * FROM crm_field_values WHERE crm_field_id IN (1455,1450);\n\nSELECT * FROM crm_field_data WHERE crm_layout_entity_id = 971;\nSELECT * FROM crm_field_data WHERE crm_layout_entity_id IN (6494,6495,6496,6497,6498,6499);\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\n on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 2 and sa.provider = 'hubspot';\n\nselect * from social_accounts where id = 1499;\n\nselect * from opportunities where team_id = 2\nand crm_provider_id IN ('51317301383');\n\nselect * from contacts where id = 85;\n\nselect * from opportunities where team_id = 2 order by id desc;\nselect * from opportunities where team_id = 2 and crm_provider_id = '51317301383'; # 5112\nselect * from opportunities where team_id = 2 and crm_provider_id = '55976759904'; # 5112\nselect * from opportunity_contacts where opportunity_id = 5117;\nselect * from crm_field_data where object_id = 1365;\nSELECT * FROM crm_fields WHERE id IN (1405, 1407, 1972, 2128);\n\nselect * from features;\nselect * from team_features where team_id IN (1);\nselect * from team_features where feature_id IN (36);\n\nSHOW CREATE TABLE opportunity_contacts;\nSELECT * FROM opportunity_contacts WHERE crm_provider_id = '111751';\n\n# $slug = 'HUBSPOT_WEBHOOK_SYNC';\n# $team = Jiminny\\Models\\Team::find(2);\n# $feature = Feature::query()->where('slug', $slug)->first();\n# TeamFeature::query()->create(['feature_id' => $feature->getId(),'team_id' => $team->getId()]);\n\n# hubspot_webhook_metrics\n\nselect * from opportunities where team_id = 2 and crm_provider_id IN ('374720564','14527423589','49908861993','50435771779'); # 1365\nSELECT * FROM opportunity_contacts WHERE opportunity_id = '414';\nSELECT * FROM opportunity_contacts WHERE crm_provider_id = '131501';\nselect * from contacts where id in (414, 464);\n\nselect * from activities where crm_configuration_id = 2;\n\nselect settings from crm_configurations where id = 11;\n\nselect * from teams; # 1, 2\nselect * from users;\nselect * from crm_configurations where id = 39;\nselect * from team_features where team_id = 2;\nselect * from features;\n# SELECT * FROM opportunities WHERE crm_configuration_id = 2\n# order by id desc;\n# and crm_provider_id = '49908861993';\n\n\nselect * from activity_providers where id IN (443, 202, 203, 227);\n\nselect * from activity_imports where id = 795889;\n\nselect c.id, c.provider, c.settings, t.* from teams t join crm_configurations c on t.id = c.team_id\nwhere c.provider = 'hubspot';\n\nselect * from crm_configurations crm JOIN teams t on crm.team_id = t.id\nwhere provider = 'hubspot';\nSELECT * FROM teams WHERE id = 31;\nSELECT * FROM users WHERE id = 257;\nSELECT * FROM opportunities WHERE team_id = 2;\n\nselect * from opportunity_contacts where opportunity_id = 5124;\nselect * from contacts where id IN (3850,3853,3851,4073,4140,4155,4480,4530,4623,5986,513,687,1806,1523,3613)\n\nselect * from activities where crm_configuration_id = 13;\n\nSELECT * FROM activities WHERE uuid_to_bin('826619ce-ec8e-4e59-8467-a01f5f6ad71e') = uuid; # 418141\n\n\nselect id, team_id, crm_provider_id from crm_configurations where provider = 'hubspot' and crm_provider_id IS NOT NULL;\nSELECT * FROM accounts WHERE team_id = 2 and crm_provider_id = '1212213464' order by id desc;\nSELECT * FROM contacts WHERE team_id = 2 and account_id = 5189 order by id desc;\nSELECT * FROM contacts WHERE team_id = 2 order by id desc;\nselect * from opportunity_contacts where contact_id = 6223;\nSELECT * FROM opportunities WHERE team_id = 2 and account_id = 5189 order by id desc;\n\nselect * from crm_profiles where crm_configuration_id = 2;\n\nselect * from activities where account_id = 46;","depth":4,"on_screen":true,"value":"# **************************** HS **************************************\n\nselect * from teams where id = 2; # 2\nselect * from features; # 2\nselect * from team_features where team_id = 2; # 2\nselect * from crm_configurations where id = 2; # 2\nselect * from users where team_id = 2; #\nselect * from playbooks where team_id = 2; # event 38\nselect * from playbook_categories where playbook_id = 38; #\n\nSELECT * FROM activities WHERE crm_configuration_id = 2 and crm_provider_id is not null order by id desc;\nhttps://app.hubspot.com/contacts/4392066/deal/16964514951/?engagement=96069102624\n https://app.staging.jiminny.com/playback/d5df34dc-bd66-4ff5-a7b3-8d3be30322a0\n\nSELECT * FROM activities WHERE uuid_to_bin('04fdcd0d-818f-4c53-92dc-6f18bc753ffd') = uuid;\n# 609126 softphone tr. 11241\n\nSELECT * FROM activities WHERE uuid_to_bin('6521bfcd-5a30-46e5-9f74-5440fd48befd') = uuid;\n# 608874 conference tr. 11226 crmId: 103422236596\n\nselect * from ai_prompts where transcription_id IN (11241, 11226);\nselect * from activity_summary_logs where activity_id = 608874;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nselect * from crm_field_data where activity_id = 1223;\n\nselect * from crm_layouts where crm_configuration_id = 2;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id IN (554);\nselect * from crm_fields where crm_configuration_id = 11 and object_type = 'event';\nSELECT * FROM crm_field_values WHERE crm_field_id IN (1455,1450);\n\nSELECT * FROM crm_field_data WHERE crm_layout_entity_id = 971;\nSELECT * FROM crm_field_data WHERE crm_layout_entity_id IN (6494,6495,6496,6497,6498,6499);\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\n on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 2 and sa.provider = 'hubspot';\n\nselect * from social_accounts where id = 1499;\n\nselect * from opportunities where team_id = 2\nand crm_provider_id IN ('51317301383');\n\nselect * from contacts where id = 85;\n\nselect * from opportunities where team_id = 2 order by id desc;\nselect * from opportunities where team_id = 2 and crm_provider_id = '51317301383'; # 5112\nselect * from opportunities where team_id = 2 and crm_provider_id = '55976759904'; # 5112\nselect * from opportunity_contacts where opportunity_id = 5117;\nselect * from crm_field_data where object_id = 1365;\nSELECT * FROM crm_fields WHERE id IN (1405, 1407, 1972, 2128);\n\nselect * from features;\nselect * from team_features where team_id IN (1);\nselect * from team_features where feature_id IN (36);\n\nSHOW CREATE TABLE opportunity_contacts;\nSELECT * FROM opportunity_contacts WHERE crm_provider_id = '111751';\n\n# $slug = 'HUBSPOT_WEBHOOK_SYNC';\n# $team = Jiminny\\Models\\Team::find(2);\n# $feature = Feature::query()->where('slug', $slug)->first();\n# TeamFeature::query()->create(['feature_id' => $feature->getId(),'team_id' => $team->getId()]);\n\n# hubspot_webhook_metrics\n\nselect * from opportunities where team_id = 2 and crm_provider_id IN ('374720564','14527423589','49908861993','50435771779'); # 1365\nSELECT * FROM opportunity_contacts WHERE opportunity_id = '414';\nSELECT * FROM opportunity_contacts WHERE crm_provider_id = '131501';\nselect * from contacts where id in (414, 464);\n\nselect * from activities where crm_configuration_id = 2;\n\nselect settings from crm_configurations where id = 11;\n\nselect * from teams; # 1, 2\nselect * from users;\nselect * from crm_configurations where id = 39;\nselect * from team_features where team_id = 2;\nselect * from features;\n# SELECT * FROM opportunities WHERE crm_configuration_id = 2\n# order by id desc;\n# and crm_provider_id = '49908861993';\n\n\nselect * from activity_providers where id IN (443, 202, 203, 227);\n\nselect * from activity_imports where id = 795889;\n\nselect c.id, c.provider, c.settings, t.* from teams t join crm_configurations c on t.id = c.team_id\nwhere c.provider = 'hubspot';\n\nselect * from crm_configurations crm JOIN teams t on crm.team_id = t.id\nwhere provider = 'hubspot';\nSELECT * FROM teams WHERE id = 31;\nSELECT * FROM users WHERE id = 257;\nSELECT * FROM opportunities WHERE team_id = 2;\n\nselect * from opportunity_contacts where opportunity_id = 5124;\nselect * from contacts where id IN (3850,3853,3851,4073,4140,4155,4480,4530,4623,5986,513,687,1806,1523,3613)\n\nselect * from activities where crm_configuration_id = 13;\n\nSELECT * FROM activities WHERE uuid_to_bin('826619ce-ec8e-4e59-8467-a01f5f6ad71e') = uuid; # 418141\n\n\nselect id, team_id, crm_provider_id from crm_configurations where provider = 'hubspot' and crm_provider_id IS NOT NULL;\nSELECT * FROM accounts WHERE team_id = 2 and crm_provider_id = '1212213464' order by id desc;\nSELECT * FROM contacts WHERE team_id = 2 and account_id = 5189 order by id desc;\nSELECT * FROM contacts WHERE team_id = 2 order by id desc;\nselect * from opportunity_contacts where contact_id = 6223;\nSELECT * FROM opportunities WHERE team_id = 2 and account_id = 5189 order by id desc;\n\nselect * from crm_profiles where crm_configuration_id = 2;\n\nselect * from activities where account_id = 46;","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":"18","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","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\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n\n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n\n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-8273650413981046499
|
923236393998005837
|
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
Sync Changes
Hide This Notification
Code changed:
Hide
6
1
6
Previous Highlighted Error
Next Highlighted Error
# [PASSWORD_DOTS] HS [PASSWORD_DOTS]
select * from teams where id = 2; # 2
select * from features; # 2
select * from team_features where team_id = 2; # 2
select * from crm_configurations where id = 2; # 2
select * from users where team_id = 2; #
select * from playbooks where team_id = 2; # event 38
select * from playbook_categories where playbook_id = 38; #
SELECT * FROM activities WHERE crm_configuration_id = 2 and crm_provider_id is not null order by id desc;
[URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4518
|
166
|
6
|
2026-05-07T14:07:28.474260+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778162848474_m2.jpg...
|
PhpStorm
|
faVsco.js – HS_local [jiminny@localhost]
|
True
|
NULL
|
monitor_2
|
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
Sync Changes
Hide This Notification
Code changed:
Hide
6
1
6
Previous Highlighted Error
Next Highlighted Error
# [PASSWORD_DOTS] HS [PASSWORD_DOTS]
select * from teams where id = 2; # 2
select * from features; # 2
select * from team_features where team_id = 2; # 2
select * from crm_configurations where id = 2; # 2
select * from users where team_id = 2; #
select * from playbooks where team_id = 2; # event 38
select * from playbook_categories where playbook_id = 38; #
SELECT * FROM activities WHERE crm_configuration_id = 2 and crm_provider_id is not null order by id desc;
[URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
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":"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":"Execute","depth":4,"bounds":{"left":0.39660904,"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.40525267,"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.4162234,"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.42486703,"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.43351063,"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":"In-Editor Results","depth":4,"bounds":{"left":0.44448137,"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":"Tx: Auto","depth":4,"bounds":{"left":0.4554521,"top":0.09896249,"width":0.024268618,"height":0.01915403},"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,"bounds":{"left":0.4820479,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"bounds":{"left":0.49301863,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.6821808,"top":0.09896249,"width":0.02825798,"height":0.01915403},"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":"6","depth":4,"bounds":{"left":0.66855055,"top":0.123703115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.67852396,"top":0.123703115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"6","depth":4,"bounds":{"left":0.6878325,"top":0.123703115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6974734,"top":0.12210695,"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.70478725,"top":0.12210695,"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":"# **************************** HS **************************************\n\nselect * from teams where id = 2; # 2\nselect * from features; # 2\nselect * from team_features where team_id = 2; # 2\nselect * from crm_configurations where id = 2; # 2\nselect * from users where team_id = 2; #\nselect * from playbooks where team_id = 2; # event 38\nselect * from playbook_categories where playbook_id = 38; #\n\nSELECT * FROM activities WHERE crm_configuration_id = 2 and crm_provider_id is not null order by id desc;\nhttps://app.hubspot.com/contacts/4392066/deal/16964514951/?engagement=96069102624\n https://app.staging.jiminny.com/playback/d5df34dc-bd66-4ff5-a7b3-8d3be30322a0\n\nSELECT * FROM activities WHERE uuid_to_bin('04fdcd0d-818f-4c53-92dc-6f18bc753ffd') = uuid;\n# 609126 softphone tr. 11241\n\nSELECT * FROM activities WHERE uuid_to_bin('6521bfcd-5a30-46e5-9f74-5440fd48befd') = uuid;\n# 608874 conference tr. 11226 crmId: 103422236596\n\nselect * from ai_prompts where transcription_id IN (11241, 11226);\nselect * from activity_summary_logs where activity_id = 608874;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nselect * from crm_field_data where activity_id = 1223;\n\nselect * from crm_layouts where crm_configuration_id = 2;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id IN (554);\nselect * from crm_fields where crm_configuration_id = 11 and object_type = 'event';\nSELECT * FROM crm_field_values WHERE crm_field_id IN (1455,1450);\n\nSELECT * FROM crm_field_data WHERE crm_layout_entity_id = 971;\nSELECT * FROM crm_field_data WHERE crm_layout_entity_id IN (6494,6495,6496,6497,6498,6499);\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\n on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 2 and sa.provider = 'hubspot';\n\nselect * from social_accounts where id = 1499;\n\nselect * from opportunities where team_id = 2\nand crm_provider_id IN ('51317301383');\n\nselect * from contacts where id = 85;\n\nselect * from opportunities where team_id = 2 order by id desc;\nselect * from opportunities where team_id = 2 and crm_provider_id = '51317301383'; # 5112\nselect * from opportunities where team_id = 2 and crm_provider_id = '55976759904'; # 5112\nselect * from opportunity_contacts where opportunity_id = 5117;\nselect * from crm_field_data where object_id = 1365;\nSELECT * FROM crm_fields WHERE id IN (1405, 1407, 1972, 2128);\n\nselect * from features;\nselect * from team_features where team_id IN (1);\nselect * from team_features where feature_id IN (36);\n\nSHOW CREATE TABLE opportunity_contacts;\nSELECT * FROM opportunity_contacts WHERE crm_provider_id = '111751';\n\n# $slug = 'HUBSPOT_WEBHOOK_SYNC';\n# $team = Jiminny\\Models\\Team::find(2);\n# $feature = Feature::query()->where('slug', $slug)->first();\n# TeamFeature::query()->create(['feature_id' => $feature->getId(),'team_id' => $team->getId()]);\n\n# hubspot_webhook_metrics\n\nselect * from opportunities where team_id = 2 and crm_provider_id IN ('374720564','14527423589','49908861993','50435771779'); # 1365\nSELECT * FROM opportunity_contacts WHERE opportunity_id = '414';\nSELECT * FROM opportunity_contacts WHERE crm_provider_id = '131501';\nselect * from contacts where id in (414, 464);\n\nselect * from activities where crm_configuration_id = 2;\n\nselect settings from crm_configurations where id = 11;\n\nselect * from teams; # 1, 2\nselect * from users;\nselect * from crm_configurations where id = 39;\nselect * from team_features where team_id = 2;\nselect * from features;\n# SELECT * FROM opportunities WHERE crm_configuration_id = 2\n# order by id desc;\n# and crm_provider_id = '49908861993';\n\n\nselect * from activity_providers where id IN (443, 202, 203, 227);\n\nselect * from activity_imports where id = 795889;\n\nselect c.id, c.provider, c.settings, t.* from teams t join crm_configurations c on t.id = c.team_id\nwhere c.provider = 'hubspot';\n\nselect * from crm_configurations crm JOIN teams t on crm.team_id = t.id\nwhere provider = 'hubspot';\nSELECT * FROM teams WHERE id = 31;\nSELECT * FROM users WHERE id = 257;\nSELECT * FROM opportunities WHERE team_id = 2;\n\nselect * from opportunity_contacts where opportunity_id = 5124;\nselect * from contacts where id IN (3850,3853,3851,4073,4140,4155,4480,4530,4623,5986,513,687,1806,1523,3613)\n\nselect * from activities where crm_configuration_id = 13;\n\nSELECT * FROM activities WHERE uuid_to_bin('826619ce-ec8e-4e59-8467-a01f5f6ad71e') = uuid; # 418141\n\n\nselect id, team_id, crm_provider_id from crm_configurations where provider = 'hubspot' and crm_provider_id IS NOT NULL;\nSELECT * FROM accounts WHERE team_id = 2 and crm_provider_id = '1212213464' order by id desc;\nSELECT * FROM contacts WHERE team_id = 2 and account_id = 5189 order by id desc;\nSELECT * FROM contacts WHERE team_id = 2 order by id desc;\nselect * from opportunity_contacts where contact_id = 6223;\nSELECT * FROM opportunities WHERE team_id = 2 and account_id = 5189 order by id desc;\n\nselect * from crm_profiles where crm_configuration_id = 2;\n\nselect * from activities where account_id = 46;","depth":4,"on_screen":true,"value":"# **************************** HS **************************************\n\nselect * from teams where id = 2; # 2\nselect * from features; # 2\nselect * from team_features where team_id = 2; # 2\nselect * from crm_configurations where id = 2; # 2\nselect * from users where team_id = 2; #\nselect * from playbooks where team_id = 2; # event 38\nselect * from playbook_categories where playbook_id = 38; #\n\nSELECT * FROM activities WHERE crm_configuration_id = 2 and crm_provider_id is not null order by id desc;\nhttps://app.hubspot.com/contacts/4392066/deal/16964514951/?engagement=96069102624\n https://app.staging.jiminny.com/playback/d5df34dc-bd66-4ff5-a7b3-8d3be30322a0\n\nSELECT * FROM activities WHERE uuid_to_bin('04fdcd0d-818f-4c53-92dc-6f18bc753ffd') = uuid;\n# 609126 softphone tr. 11241\n\nSELECT * FROM activities WHERE uuid_to_bin('6521bfcd-5a30-46e5-9f74-5440fd48befd') = uuid;\n# 608874 conference tr. 11226 crmId: 103422236596\n\nselect * from ai_prompts where transcription_id IN (11241, 11226);\nselect * from activity_summary_logs where activity_id = 608874;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nselect * from crm_field_data where activity_id = 1223;\n\nselect * from crm_layouts where crm_configuration_id = 2;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id IN (554);\nselect * from crm_fields where crm_configuration_id = 11 and object_type = 'event';\nSELECT * FROM crm_field_values WHERE crm_field_id IN (1455,1450);\n\nSELECT * FROM crm_field_data WHERE crm_layout_entity_id = 971;\nSELECT * FROM crm_field_data WHERE crm_layout_entity_id IN (6494,6495,6496,6497,6498,6499);\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\n on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 2 and sa.provider = 'hubspot';\n\nselect * from social_accounts where id = 1499;\n\nselect * from opportunities where team_id = 2\nand crm_provider_id IN ('51317301383');\n\nselect * from contacts where id = 85;\n\nselect * from opportunities where team_id = 2 order by id desc;\nselect * from opportunities where team_id = 2 and crm_provider_id = '51317301383'; # 5112\nselect * from opportunities where team_id = 2 and crm_provider_id = '55976759904'; # 5112\nselect * from opportunity_contacts where opportunity_id = 5117;\nselect * from crm_field_data where object_id = 1365;\nSELECT * FROM crm_fields WHERE id IN (1405, 1407, 1972, 2128);\n\nselect * from features;\nselect * from team_features where team_id IN (1);\nselect * from team_features where feature_id IN (36);\n\nSHOW CREATE TABLE opportunity_contacts;\nSELECT * FROM opportunity_contacts WHERE crm_provider_id = '111751';\n\n# $slug = 'HUBSPOT_WEBHOOK_SYNC';\n# $team = Jiminny\\Models\\Team::find(2);\n# $feature = Feature::query()->where('slug', $slug)->first();\n# TeamFeature::query()->create(['feature_id' => $feature->getId(),'team_id' => $team->getId()]);\n\n# hubspot_webhook_metrics\n\nselect * from opportunities where team_id = 2 and crm_provider_id IN ('374720564','14527423589','49908861993','50435771779'); # 1365\nSELECT * FROM opportunity_contacts WHERE opportunity_id = '414';\nSELECT * FROM opportunity_contacts WHERE crm_provider_id = '131501';\nselect * from contacts where id in (414, 464);\n\nselect * from activities where crm_configuration_id = 2;\n\nselect settings from crm_configurations where id = 11;\n\nselect * from teams; # 1, 2\nselect * from users;\nselect * from crm_configurations where id = 39;\nselect * from team_features where team_id = 2;\nselect * from features;\n# SELECT * FROM opportunities WHERE crm_configuration_id = 2\n# order by id desc;\n# and crm_provider_id = '49908861993';\n\n\nselect * from activity_providers where id IN (443, 202, 203, 227);\n\nselect * from activity_imports where id = 795889;\n\nselect c.id, c.provider, c.settings, t.* from teams t join crm_configurations c on t.id = c.team_id\nwhere c.provider = 'hubspot';\n\nselect * from crm_configurations crm JOIN teams t on crm.team_id = t.id\nwhere provider = 'hubspot';\nSELECT * FROM teams WHERE id = 31;\nSELECT * FROM users WHERE id = 257;\nSELECT * FROM opportunities WHERE team_id = 2;\n\nselect * from opportunity_contacts where opportunity_id = 5124;\nselect * from contacts where id IN (3850,3853,3851,4073,4140,4155,4480,4530,4623,5986,513,687,1806,1523,3613)\n\nselect * from activities where crm_configuration_id = 13;\n\nSELECT * FROM activities WHERE uuid_to_bin('826619ce-ec8e-4e59-8467-a01f5f6ad71e') = uuid; # 418141\n\n\nselect id, team_id, crm_provider_id from crm_configurations where provider = 'hubspot' and crm_provider_id IS NOT NULL;\nSELECT * FROM accounts WHERE team_id = 2 and crm_provider_id = '1212213464' order by id desc;\nSELECT * FROM contacts WHERE team_id = 2 and account_id = 5189 order by id desc;\nSELECT * FROM contacts WHERE team_id = 2 order by id desc;\nselect * from opportunity_contacts where contact_id = 6223;\nSELECT * FROM opportunities WHERE team_id = 2 and account_id = 5189 order by id desc;\n\nselect * from crm_profiles where crm_configuration_id = 2;\n\nselect * from activities where account_id = 46;","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":"18","depth":4,"bounds":{"left":0.3600399,"top":0.2490024,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.37167552,"top":0.2490024,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"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.3879654,"top":0.24740623,"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\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n\n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n\n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"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}]...
|
-8273650413981046499
|
923236393998005837
|
visual_change
|
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
Sync Changes
Hide This Notification
Code changed:
Hide
6
1
6
Previous Highlighted Error
Next Highlighted Error
# [PASSWORD_DOTS] HS [PASSWORD_DOTS]
select * from teams where id = 2; # 2
select * from features; # 2
select * from team_features where team_id = 2; # 2
select * from crm_configurations where id = 2; # 2
select * from users where team_id = 2; #
select * from playbooks where team_id = 2; # event 38
select * from playbook_categories where playbook_id = 38; #
SELECT * FROM activities WHERE crm_configuration_id = 2 and crm_provider_id is not null order by id desc;
[URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
4516
|
NULL
|
NULL
|
NULL
|
|
13076
|
582
|
2
|
2026-05-09T10:14:04.870318+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778321644870_m2.jpg...
|
Code
|
reimport_sms.sh — finance [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: finance [SSH: nas]
Explorer Section: finance [SSH: nas]
FINANCE [SSH: NAS]
auth
dsk-uploader
finance-hub
backend
frontend
scripts
.env
.env.example
.gitignore
docker-compose.yml
sms_export.json
payments-logger
.claude
auth
backend
frontend
.env
.env.example
.gitignore
API.md
docker-compose.yml
README.md
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
docker-compose.yml, Editor Group 1
.env, Editor Group 1
report(1).csv, Editor Group 1
report(2).csv, Editor Group 1
reimport_sms.sh, preview, Editor Group 1
#!/usr/bin/env bash
# Bulk re-import SMS messages from sms_export.json into finance-hub.
# Usage: bash scripts/reimport_sms.sh [--dry-run]
#
# Each record is POSTed to POST /api/payments/ingest (public, no auth needed).
# The script prints a progress line per message and a final summary.
set -euo pipefail
EXPORT_FILE="${1:-$(dirname "$0")/../sms_export.json}"
BASE_URL="${FINANCE_HUB_URL:-[URL_WITH_CREDENTIALS] @default(autoincrement())
rawMessage String @map("raw_message")
date DateTime?
type String?
card String?
recipient String?
amount Float?
currency String? @default("EUR")
balance Float?
source Source @default(INGEST)
status Status @default(UNPROCESSED)
tags Tag[]
notifiedAt DateTime? @map("notified_at")
notifyPhone String? @map("notify_phone")
debitBgn Float? @map("debit_bgn")
creditBgn Float? @map("credit_bgn")
transactionType String? @map("transaction_type")
payerAccount String? @map("payer_account")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("payments")
}
model Tag {
id Int @id @default(autoincrement())
name String @unique
color String @default("#6b7280")
payments Payment[]
@@map("tags")
}
enum Status { UNPROCESSED SENT SKIPPED }
enum Source { INGEST UPLOAD }
```
**Key decisions:**
- No `User` model — Authentik owns identity.
- `currency`: `EUR` for SMS ingest, `BGN` for CSV uploads.
- `debitBgn`, `creditBgn`, `transactionType`, `payerAccount`: nullable CSV-only columns; INGEST rows store nulls. Avoids a union query for the unified list view.
- `balance` is always null for CSV rows (DSK export does not include running balance).
- Fresh consolidated migration — no data migration from reference apps required.
---
## API Routes
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | /api/health | public | Health check |
| POST | /api/payments/ingest | public | SMS or structured ingest (source=INGEST) |
| GET | /api/payments | required | List with filters/sort/pagination (+ source filter) |
| GET | /api/payments/meta/tags | required | All tags |
| GET | /api/payments/meta/filters | required | Filter options incl. `sources` array |
| GET | /api/payments/:id | required | Single payment |
| PATCH | /api/payments/:id | required | Update status |
| DELETE | /api/payments/:id | required | Delete |
| POST | /api/payments/:id/send | required | Send notification |
| POST | /api/payments/:id/skip | required | Skip |
| POST | /api/payments/:id/tags | required | Add/upsert tag |
| DELETE | /api/payments/:id/tags/:tagId | required | Remove tag |
| POST | /api/upload/csv | required | DSK CSV file upload (source=UPLOAD) |
---
## Key Implementation Details
### auth.js (replaces entire old auth module)
```js
const PUBLIC_PATHS = new Set(['/api/health', '/api/payments/ingest']);
function authentikMiddleware(req, res, next) {
if (PUBLIC_PATHS.has(req.path)) return next();
const username = req.headers['x-authentik-username'];
if (!username) return res.status(401).json({ error: 'Unauthorized' });
req.user = {
username,
email: req.headers['x-authentik-email'] || null,
groups: (req.headers['x-authentik-groups'] || '').split(',').map(g => g.trim()).filter(Boolean),
};
next();
}
module.exports = { authentikMiddleware };
```
### csvParser.js (port of dskuploader.py)
- `iconv-lite` decodes buffer as cp1251 (DSK Bank export encoding), falls back to UTF-8
- `csv-parse` parses the decoded text with `columns: true`
- Columns: `Дата`, `Вид на трансакцията`, `Основание`, `Дебит BGN`, `Кредит BGN`, `Наредител/Получател`, `Номер сметка на наредителя / получателя`
- Card extraction: regex `/^\d{6}x{6}\d{4}$/` on first token of `Основание`
- Skips rows where `Вид на трансакцията === 'ТРАНСФЕР СОБСТВЕНИ СМЕТКИ'`
- Auto-tags via keyword rules (ЗАПЛАТА→Salary, LIDL→Groceries, NETFLIX→Subscriptions, etc.) — same logic as Python `generate_tags()`
- Returns `{ rows: PaymentData[], skipped: number, errors: string[] }`
### payments.js changes from payments-logger
1. Add `source: 'INGEST'` and `currency` to the `/ingest` create call
2. Add `source` to the `GET /` where clause filter
3. Add `sources` to `meta/filters` response
4. Currency-aware amount formatting in notification message
5. Remove all JWT/auth references (no `/auth/register`, `/auth/login`)
### upload.js (new)
- `multer` memory storage, max 10 files × 10 MB
- Calls `parseDskCsv(buffer)` per file
- Upserts tags via `prisma.tag.upsert` then connects
- Returns `{ imported, skipped, errors, payments[] }`
### Frontend changes
- **Delete**: `auth.js`, `AuthProvider.jsx`
- **main.jsx**: Remove `<AuthProvider>` wrapper
- **App.jsx**: Replace `authFetch` with plain `fetch` (Authentik session cookie travels automatically); logout → `window.location.href = '/outpost.goauthentik.io/sign_out'`; add "Payments" / "Upload CSV" tab toggle
- **FilterBar.jsx**: Add source `<select>` (All / SMS Ingest / CSV Upload); widen grid to 5 cols
- **PaymentTable.jsx**: Add `Source` column with `SMS` (indigo) / `CSV` (emerald) badge; show `${amount} ${currency}` in amount cell
- **UploadPanel.jsx** (new): Drag-and-drop zone + file list + import button + result summary with error accordion; calls `POST /api/upload/csv` with `FormData`
---
## Docker Compose
```yaml
services:
db:
image: postgres:16-alpine
environment: { POSTGRES_USER: finance, POSTGRES_PASSWORD: [PASSWORD] POSTGRES_DB: finance_hub }
volumes: [pgdata:/var/lib/postgresql/data]
healthcheck: { test: pg_isready -U finance -d finance_hub, interval: 5s }
backend:
build: ./backend
environment:
DATABASE_URL: [CONNECTION_STRING]
PORT: "3001"
NOTIFIER_URL: ${NOTIFIER_URL}
NOTIFIER_CHANNEL: ${NOTIFIER_CHANNEL:-viber}
NOTIFY_DEFAULT_PHONE: ${NOTIFY_DEFAULT_PHONE}
TZ: ${TZ:-Europe/Sofia}
ports: ["${BACKEND_PORT:-3001}:3001"]
depends_on: { db: { condition: service_healthy } }
frontend:
build: ./frontend
ports: ["${FRONTEND_PORT:-5175}:5173"]
depends_on: [backend]
volumes: { pgdata: }
```
**NPM setup:** Frontend port proxied through Authentik forward auth. Backend port exposed separately (unprotected) so the public `/api/payments/ingest` remains reachable by iOS Shortcuts / SMS gateways without login.
---
## Environment Variables (.env)
```bash
[ENV_SECRET]
NOTIFIER_URL=[URL_WITH_CREDENTIALS] @default(autoincrement())
rawMessage String @map("raw_message")
date DateTime?
type String?
card String?
recipient String?
amount Float?
currency String? @default("EUR")
balance Float?
source Source @default(INGEST)
status Status @default(UNPROCESSED)
tags Tag[]
notifiedAt DateTime? @map("notified_at")
notifyPhone String? @map("notify_phone")
debitBgn Float? @map("debit_bgn")
creditBgn Float? @map("credit_bgn")
transactionType String? @map("transaction_type")
payerAccount String? @map("payer_account")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("payments")
}
model Tag {
id Int @id @default(autoincrement())
name String @unique
color String @default("#6b7280")
payments Payment[]
@@map("tags")
}
enum Status {
UNPROCESSED
SENT
SKIPPED
}
enum Source {
INGEST
UPLOAD
}
Write
migration.sql
migration.sql
55 lines
-- CreateEnum
CREATE TYPE "Status" AS ENUM ('UNPROCESSED', 'SENT', 'SKIPPED');
CREATE TYPE "Source" AS ENUM ('INGEST', 'UPLOAD');
-- CreateTable
CREATE TABLE "payments" (
"id" SERIAL PRIMARY KEY,
"raw_message" TEXT NOT NULL,
"date" TIMESTAMP(3),
"type" TEXT,
"card" TEXT,
"recipient" TEXT,
"amount" DOUBLE PRECISION,
"currency" TEXT DEFAULT 'EUR',
"balance" DOUBLE PRECISION,
"source" "Source" NOT NULL DEFAULT 'INGEST',
"status" "Status" NOT NULL DEFAULT 'UNPROCESSED',
"notified_at" TIMESTAMP(3),
"notify_phone" TEXT,
"debit_bgn" DOUBLE PRECISION,
"credit_bgn" DOUBLE PRECISION,
"transaction_type" TEXT,
"payer_account" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- CreateTable
CREATE TABLE "tags" (
"id" SERIAL PRIMARY KEY,
"name" TEXT NOT NULL,
"color" TEXT NOT NULL DEFAULT '#6b7280'
);
-- CreateUniqueIndex
CREATE UNIQUE INDEX "tags_name_key" ON "tags"("name");
-- CreateTable (M2M join)
CREATE TABLE "_PaymentToTag" (
"A" INTEGER NOT NULL,
"B" INTEGER NOT NULL,
CONSTRAINT "_PaymentToTag_AB_pkey" PRIMARY KEY ("A", "B")
);
CREATE INDEX "_PaymentToTag_B_index" ON "_PaymentToTag"("B");
-- AddForeignKey
ALTER TABLE "_PaymentToTag"
ADD CONSTRAINT "_PaymentToTag_A_fkey"
FOREIGN KEY ("A") REFERENCES "payments"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "_PaymentToTag"
ADD CONSTRAINT "_PaymentToTag_B_fkey"
FOREIGN KEY ("B") REFERENCES "tags"("id") ON DELETE CASCADE ON UPDATE CASCADE;
Write
migration_lock.toml
migration_lock.toml
4 lines
# Please do not edit this file manually
# It should be added in your version-control system (e.g., Git)
provider = "postgresql"
Update Todos
Create folder structure and root config files
Write backend Prisma schema and migration
Write backend package.json and Dockerfile
Write backend src files (auth, parser, csvParser, index)
Write backend routes (payments.js, upload.js)
Write frontend config files
Write frontend React components
Build and verify with docker compose
Write
package.json
package.json
26 lines
{
"name": "finance-hub-backend",
"version": "1.0.0",
"main": "src/index.js",
"scripts": {
"start": "node src/index.js",
"dev": "nodemon src/index.js",
"prisma:generate": "prisma generate",
"prisma:migrate": "prisma migrate deploy"
},
"dependencies": {
"@prisma/client": "^5.22.0",
"cors": "^2.8.5",
"csv-parse": "^5.5.6",
"express": "^4.21.1",
"express-rate-limit": "^7.4.0",
"iconv-lite": "^0.6.3",
"morgan": "^1.10.0",
"multer": "^1.4.5-lts.1"
},
"devDependencies": {
"nodemon": "^3.1.7",
"prisma": "^5.22.0"
}
}
Write
Dockerfile
Dockerfile
18 lines
FROM node:20-alpine
RUN apk add --no-cache openssl
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm install
COPY prisma ./prisma
RUN npx prisma generate
COPY src ./src
EXPOSE 3001
CMD ["sh", "-c", "npx prisma migrate deploy && node src/index.js"]
Update Todos
Create folder structure and root config files
Write backend Prisma schema and migration
Write backend package.json and Dockerfile
Write backend src files (auth, parser, csvParser, index)
Write backend routes (payments.js, upload.js)
Write frontend config files
Write frontend React components
Build and verify with docker compose
Write
auth.js
auth.js
27 lines
const PUBLIC_PATHS = new Set([
'/api/health',
'/api/payments/ingest',
]);
function authentikMiddleware(req, res, next) {
if (PUBLIC_PATHS.has(req.path)) return next();
const username = req.headers['x-authentik-username'];
if (!username) {
return res.status(401).json({ error: 'Unauthorized — missing Authentik session' });
}
req.user = {
username,
email: req.headers['x-authentik-email'] || null,
groups: (req.headers['x-authentik-groups'] || '')
.split(',')
.map(g => g.trim())
.filter(Boolean),
};
next();
}
module.exports = { authentikMiddleware };
Write
parser.js
parser.js
104 lines
/**
* Parses SMS payment messages from Bulgarian banks (DSK Bank, etc.)
*
* Supported formats:
*
* POS / INTERNET / ECOM / P2P payment:
* DSK Bank. Na DD/MM/YYYY v HH:MM sa plateni AMOUNT CURRENCY s karta CARD na POS s adres: RECIPIENT. Nalichni: BALANCE CURRENCY.
*
* ATM withdrawal:
* DSK Bank. Na DD/MM/YYYY v HH:MM sa iztegleni AMOUNT CURRENCY s karta CARD ot ATM s adres: RECIPIENT. Nalichni: BALANCE CURRENCY.
*
* ATM utility payment (amount may include fee as AMOUNT/FEE):
* DSK Bank. Na DD/MM/YYYY v HH:MM sa plateni AMOUNT CURRENCY/FEE CURRENCY s karta CARD na ATM s adres:RECIPIENT. Nalichni: BALANCE CURRENCY.
*/
const LOCAL_TZ = process.env.TZ || 'Europe/Sofia';
/**
* Convert a local-timezone date/time to a UTC Date object.
* Uses Intl to resolve the actual UTC offset (DST-aware).
*/
function localToUtc(year, month, day, hour, minute) {
const naive = new Date(Date.UTC(year, month - 1, day, hour, minute, 0));
const formatter = new Intl.DateTimeFormat('en-US', {
timeZone: LOCAL_TZ,
year: 'numeric', month: '2-digit', day: '2-digit',
hour: '2-digit', minute: '2-digit', second: '2-digit',
hour12: false,
});
const parts = {};
formatter.formatToParts(naive).forEach(p => { parts[p.type] = p.value; });
const localAtNaive = new Date(Date.UTC(
parseInt(parts.year), parseInt(parts.month) - 1, parseInt(parts.day),
parseInt(parts.hour) % 24, parseInt(parts.minute), parseInt(parts.second),
));
const offsetMs = localAtNaive.getTime() - naive.getTime();
return new Date(Date.UTC(year, month - 1, day, hour, minute, 0) - offsetMs);
}
function parsePaymentSms(message) {
const result = {
rawMessage: message,
date: null,
type: null,
card: null,
recipient: null,
amount: null,
balance: null,
};
// Date and time: "Na DD/MM/YYYY v HH:MM"
const dateMatch = message.match(/Na (\d{2})\/(\d{2})\/(\d{4}) v (\d{2}):(\d{2})/i);
if (dateMatch) {
const [, day, month, year, hour, minute] = dateMatch;
result.date = localToUtc(
parseInt(year), parseInt(month), parseInt(day),
parseInt(hour), parseInt(minute),
);
}
// Card mask: "s karta 400915***4447" or "s karta 483890***7162"
const cardMatch = message.match(/s karta\s+([\d*]+)/i);
if (cardMatch) {
result.card = cardMatch[1];
}
// Transaction type: supports both prepositions
// "na POS" / "na ATM" / "na INTERNET" etc. (payment)
// "ot ATM" (withdrawal)
const typeMatch = message.match(/(?:na|ot)\s+(POS|ATM|INTERNET|ECOM|P2P)\b/i);
if (typeMatch) {
result.type = typeMatch[1].toUpperCase();
}
// Recipient address: "s adres: MERCHANT" or "s adres:MERCHANT" (no space variant)
const recipientMatch = message.match(/s adres:\s*([^.]+)\./i);
if (recipientMatch) {
result.recipient = recipientMatch[1].trim();
}
// Amount: handles both verbs and the AMOUNT/FEE suffix format
// "sa plateni 7.78 EUR"
// "sa iztegleni 400.00 EUR"
// "sa plateni 0.50 EUR/0.50 EUR" → captures 0.50 (the charged amount, ignoring fee)
const amountMatch = message.match(/sa (?:plateni|iztegleni)\s+([\d.,]+)\s+[A-Z]{3}/i);
if (amountMatch) {
result.amount = parseFloat(amountMatch[1].replace(',', '.'));
}
// Balance: "Nalichni: 2583.07 EUR."
const balanceMatch = message.match(/Nalichni:\s*([\d.,]+)\s+[A-Z]{3}/i);
if (balanceMatch) {
result.balance = parseFloat(balanceMatch[1].replace(',', '.'));
}
return result;
}
module.exports = { parsePaymentSms };
Write
csvParser.js
csvParser.js
175 lines
/**
* DSK Bank CSV parser — Node.js port of dskuploader.py
*
* DSK Bank exports use Windows-1251 (cp1251) encoding.
* Each row maps to a Payment record with source=UPLOAD, currency=BGN.
*/
const { parse } = require('csv-parse');
const iconv = require('iconv-lite');
const SKIP_TYPE = 'ТРАНСФЕР СОБСТВЕНИ СМЕТКИ';
const CARD_REGEX = /^\d{6}x{6}\d{4}$/;
const POS_REGEX = /^\s*ПЛАЩАНЕ\s+НА\s+ПОС\s+\d{2}\.\d{2}\.\d{4}\s+\d{2}:\d{2}/;
const COL = {
DATE: 'Дата',
TYPE: 'Вид на трансакцията',
REASON: 'Основание',
DEBIT: 'Дебит BGN',
CREDIT: 'Кредит BGN',
PAYEE: 'Наредител/Получател',
ACCT: 'Номер сметка на наредителя / получателя',
};
const TAG_RULES = [
['reason', 'ЗАПЛАТА', 'Salary'],
['reason', 'ТЕГЛЕНЕ НА ATM', 'ATM'],
['reason', 'ПЛАЩАНЕ ПО ЗАЕМ', 'Home Credit'],
['reason', 'АВТ.ТАКСА ОБСЛУЖВАНЕ', 'Bills'],
['transactionType', 'КОМУНАЛНИ УСЛУГИ', 'Bills'],
['payee', 'VIVACOM', 'Subscriptions'],
['payee', 'Google', 'Subscriptions'],
['payee', 'SkyShowtime', 'Subscriptions'],
['payee', 'NETFLIX', 'Subscriptions'],
['payee', 'LUKOIL', 'Bills'],
['payee', 'CityGate', 'Bills'],
['payee', 'CBA', 'Groceries'],
['payee', 'FANTASTICO', 'Groceries'],
['payee', 'LIDL', 'Groceries'],
];
function parseNum(val) {
if (val == null || val === '') return null;
if (typeof val === 'number') return isNaN(val) ? null : val;
const s = String(val).trim().replace(/\xa0/g, '').replace(/ /g, '').replace(',', '.');
const n = parseFloat(s);
return isNaN(n) ? null : n;
}
function parseDate(val) {
if (!val) return null;
const s = String(val).trim();
const m = s.match(/^(\d{2})\.(\d{2})\.(\d{4})$/);
if (m) {
return new Date(Date.UTC(parseInt(m[3]), parseInt(m[2]) - 1, parseInt(m[1])));
}
return null;
}
function processReasonAndCard(reason) {
if (!reason || typeof reason !== 'string') return { reason: '', card: null };
const parts = reason.trim().split(' ');
let card = null;
let cleanReason = reason.trim();
if (parts[0] && CARD_REGEX.test(parts[0])) {
card = parts[0];
cleanReason = parts.slice(1).join(' ').trim();
}
if (POS_REGEX.test(cleanReason)) {
const posParts = cleanReason.split('<br/>');
try {
const dateTime = posParts[0].split('ПОС ')[1];
cleanReason = `POS PAYMENT ${dateTime}`;
} catch (_) { /* keep original */ }
}
return { reason: cleanReason.replace(/\s+/g, ' ').trim(), card };
}
function generateTags(fields) {
const tags = new Set();
for (const [field, keyword, tagName] of TAG_RULES) {
if ((fields[field] || '').includes(keyword)) {
tags.add(tagName);
}
}
return Array.from(tags);
}
function processRow(row) {
const transactionType = (row[COL.TYPE] || '').trim();
if (transactionType === SKIP_TYPE) return null;
const { reason, card } = processReasonAndCard(row[COL.REASON]);
const payee = (row[COL.PAYEE] || '').trim();
const payerAccount = (row[COL.ACCT] || '').trim();
const debitBgn = parseNum(row[COL.DEBIT]);
const creditBgn = parseNum(row[COL.CREDIT]);
const date = parseDate(row[COL.DATE]);
const autoTags = generateTags({ reason, transactionType, payee, debitBgn, creditBgn });
const amount = debitBgn ?? creditBgn ?? null;
const rawMessage = [
row[COL.DATE] && `Date: ${row[COL.DATE]}`,
transactionType && `Type: ${transactionType}`,
payee && `Payee: ${payee}`,
debitBgn != null && `Debit: ${debitBgn} BGN`,
creditBgn != null && `Credit: ${creditBgn} BGN`,
].filter(Boolean).join(' | ');
return {
rawMessage,
date,
type: null,
card,
recipient: payee || null,
amount,
currency: 'BGN',
balance: null,
source: 'UPLOAD',
debitBgn,
creditBgn,
transactionType: transactionType || null,
payerAccount: payerAccount || null,
autoTags,
};
}
/**
* Parse a Buffer containing a DSK Bank CSV (cp1251 or UTF-8).
* Returns { rows, skipped, errors }.
*/
async function parseDskCsv(buffer) {
// Try cp1251 first (DSK Bank export encoding), fall back to UTF-8
let text = iconv.decode(buffer, 'cp1251');
if (!text.includes(COL.DATE)) {
text = buffer.toString('utf-8');
}
return new Promise((resolve, reject) => {
const rows = [];
const errors = [];
let skipped = 0;
const parser = parse(text, {
columns: true,
skip_...
|
[{"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: finance [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: finance [SSH: nas]","depth":22,"bounds":{"left":0.022606382,"top":0.07581804,"width":0.039228722,"height":0.017557861},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"FINANCE [SSH: NAS]","depth":23,"bounds":{"left":0.022606382,"top":0.079010375,"width":0.039228722,"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":17,"bounds":{"left":0.024933511,"top":0.07980846,"width":0.036901597,"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":"auth","depth":27,"bounds":{"left":0.025930852,"top":0.09577015,"width":0.008976064,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.025930852,"top":0.096568234,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":3,"bounds":{"left":0.02825798,"top":0.096568234,"width":0.0066489363,"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":"dsk-uploader","depth":27,"bounds":{"left":0.025930852,"top":0.11332801,"width":0.026928192,"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":11,"bounds":{"left":0.028590426,"top":0.11412609,"width":0.024268618,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.019614361,"top":0.13088587,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"finance-hub","depth":27,"bounds":{"left":0.025930852,"top":0.13088587,"width":0.024268618,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.025930852,"top":0.13168396,"width":0.0016622341,"height":0.011971269}},{"char_start":1,"char_count":10,"bounds":{"left":0.027593086,"top":0.13168396,"width":0.022938829,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.022273935,"top":0.14844373,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":27,"bounds":{"left":0.028590426,"top":0.14844373,"width":0.017287234,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.14924182,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":6,"bounds":{"left":0.03125,"top":0.14924182,"width":0.01462766,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.022273935,"top":0.1660016,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"frontend","depth":27,"bounds":{"left":0.028590426,"top":0.1660016,"width":0.017287234,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.16679968,"width":0.0016622341,"height":0.011971269}},{"char_start":1,"char_count":7,"bounds":{"left":0.03025266,"top":0.16679968,"width":0.015625,"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":"scripts","depth":27,"bounds":{"left":0.028590426,"top":0.18355946,"width":0.013630319,"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":6,"bounds":{"left":0.030917553,"top":0.18435754,"width":0.011303191,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.021276595,"top":0.19952115,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".env","depth":27,"bounds":{"left":0.028590426,"top":0.20111732,"width":0.00831117,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.2019154,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":3,"bounds":{"left":0.029920213,"top":0.2019154,"width":0.006981383,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.021276595,"top":0.21707901,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".env.example","depth":27,"bounds":{"left":0.028590426,"top":0.21867518,"width":0.025930852,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.21947326,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":11,"bounds":{"left":0.029920213,"top":0.21947326,"width":0.024933511,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.021276595,"top":0.23463687,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".gitignore","depth":27,"bounds":{"left":0.028590426,"top":0.23623304,"width":0.018949468,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.23703113,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":9,"bounds":{"left":0.029920213,"top":0.23703113,"width":0.017952127,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.021276595,"top":0.25219473,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"docker-compose.yml","depth":27,"bounds":{"left":0.028590426,"top":0.25379092,"width":0.042220745,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.254589,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":17,"bounds":{"left":0.03125,"top":0.254589,"width":0.03956117,"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":"sms_export.json","depth":27,"bounds":{"left":0.028590426,"top":0.27134877,"width":0.032912236,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.27214685,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":14,"bounds":{"left":0.030917553,"top":0.27214685,"width":0.030917553,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.019614361,"top":0.28890663,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"payments-logger","depth":27,"bounds":{"left":0.025930852,"top":0.28890663,"width":0.034574468,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.025930852,"top":0.2897047,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":14,"bounds":{"left":0.028590426,"top":0.2897047,"width":0.031914894,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.022273935,"top":0.3064645,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".claude","depth":27,"bounds":{"left":0.028590426,"top":0.3064645,"width":0.01462766,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.30726257,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":6,"bounds":{"left":0.029920213,"top":0.30726257,"width":0.013297873,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.022273935,"top":0.32402235,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"auth","depth":27,"bounds":{"left":0.028590426,"top":0.32402235,"width":0.008976064,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.32482043,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":3,"bounds":{"left":0.030917553,"top":0.32482043,"width":0.0066489363,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.022273935,"top":0.3415802,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":27,"bounds":{"left":0.028590426,"top":0.3415802,"width":0.017287234,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.3423783,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":6,"bounds":{"left":0.03125,"top":0.3423783,"width":0.01462766,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.022273935,"top":0.35913807,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"frontend","depth":27,"bounds":{"left":0.028590426,"top":0.35913807,"width":0.017287234,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.35993615,"width":0.0016622341,"height":0.011971269}},{"char_start":1,"char_count":7,"bounds":{"left":0.03025266,"top":0.35993615,"width":0.015625,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.021276595,"top":0.37509975,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".env","depth":27,"bounds":{"left":0.028590426,"top":0.37669593,"width":0.00831117,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.377494,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":3,"bounds":{"left":0.029920213,"top":0.377494,"width":0.006981383,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.021276595,"top":0.3926576,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".env.example","depth":27,"bounds":{"left":0.028590426,"top":0.3942538,"width":0.025930852,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.39505187,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":11,"bounds":{"left":0.029920213,"top":0.39505187,"width":0.024933511,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.021276595,"top":0.4102155,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".gitignore","depth":27,"bounds":{"left":0.028590426,"top":0.41181165,"width":0.018949468,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.41260973,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":9,"bounds":{"left":0.029920213,"top":0.41260973,"width":0.017952127,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.021276595,"top":0.42777336,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"API.md","depth":27,"bounds":{"left":0.028590426,"top":0.4293695,"width":0.014295213,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.4301676,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":5,"bounds":{"left":0.03158245,"top":0.4301676,"width":0.011303191,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.021276595,"top":0.44533122,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"docker-compose.yml","depth":27,"bounds":{"left":0.028590426,"top":0.44692737,"width":0.042220745,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.44772545,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":17,"bounds":{"left":0.03125,"top":0.44772545,"width":0.03956117,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.021276595,"top":0.46288908,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"README.md","depth":27,"bounds":{"left":0.028590426,"top":0.46448523,"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":"docker-compose.yml, Editor Group 1","depth":28,"bounds":{"left":0.11569149,"top":0.047885075,"width":0.0625,"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":".env, Editor Group 1","depth":28,"bounds":{"left":0.17785904,"top":0.047885075,"width":0.040226065,"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":"report(1).csv, Editor Group 1","depth":28,"bounds":{"left":0.21775267,"top":0.047885075,"width":0.046210106,"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":"report(2).csv, Editor Group 1","depth":28,"bounds":{"left":0.26396278,"top":0.047885075,"width":0.046875,"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":"reimport_sms.sh, preview, Editor Group 1","depth":28,"bounds":{"left":0.31050533,"top":0.047885075,"width":0.05418883,"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.14527926,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.16422872,"top":0.07821229,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextArea","text":"#!/usr/bin/env bash\n# Bulk re-import SMS messages from sms_export.json into finance-hub.\n# Usage: bash scripts/reimport_sms.sh [--dry-run]\n#\n# Each record is POSTed to POST /api/payments/ingest (public, no auth needed).\n# The script prints a progress line per message and a final summary.\n\nset -euo pipefail\n\nEXPORT_FILE=\"${1:-$(dirname \"$0\")/../sms_export.json}\"\nBASE_URL=\"${FINANCE_HUB_URL:-http://localhost:3001}\"\nDRY_RUN=false\n[[ \"${1:-}\" == \"--dry-run\" || \"${2:-}\" == \"--dry-run\" ]] && DRY_RUN=true\n\nif [[ ! -f \"$EXPORT_FILE\" ]]; then\n echo \"ERROR: export file not found: $EXPORT_FILE\"\n exit 1\nfi\n\ntotal=$(python3 -c \"import json; print(len(json.load(open('$EXPORT_FILE'))))\")\necho \"Importing $total SMS messages from $EXPORT_FILE → $BASE_URL\"\n$DRY_RUN && echo \"(DRY RUN — no requests will be sent)\"\n\nok=0; fail=0; idx=0\n\npython3 -c \"\nimport json, sys\nrecords = json.load(open('$EXPORT_FILE'))\nfor r in records:\n print(json.dumps({'message': r['message']}))\n\" | while IFS= read -r body; do\n idx=$((idx + 1))\n msg_preview=$(echo \"$body\" | python3 -c \"import json,sys; d=json.load(sys.stdin); print(d['message'][:60])\" 2>/dev/null || echo \"(parse error)\")\n\n if $DRY_RUN; then\n echo \"[$idx/$total] DRY: $msg_preview\"\n continue\n fi\n\n http_code=$(curl -s -o /tmp/_reimport_resp.json -w \"%{http_code}\" \\\n -X POST \"$BASE_URL/api/payments/ingest\" \\\n -H \"Content-Type: application/json\" \\\n -d \"$body\" 2>/dev/null)\n\n if [[ \"$http_code\" == \"201\" ]]; then\n echo \"[$idx/$total] OK $msg_preview\"\n ok=$((ok + 1))\n else\n resp=$(cat /tmp/_reimport_resp.json 2>/dev/null || echo \"(no response)\")\n echo \"[$idx/$total] ERR $http_code — $msg_preview\"\n echo \" $resp\"\n fail=$((fail + 1))\n fi\n\n # Rate-limit slightly to avoid hammering the server\n sleep 0.05\ndone\n\necho \"\"\necho \"Done. OK=$ok FAILED=$fail TOTAL=$total\"","depth":28,"bounds":{"left":0.13763298,"top":0.0933759,"width":0.35073137,"height":0.014365523},"on_screen":true,"value":"#!/usr/bin/env bash\n# Bulk re-import SMS messages from sms_export.json into finance-hub.\n# Usage: bash scripts/reimport_sms.sh [--dry-run]\n#\n# Each record is POSTed to POST /api/payments/ingest (public, no auth needed).\n# The script prints a progress line per message and a final summary.\n\nset -euo pipefail\n\nEXPORT_FILE=\"${1:-$(dirname \"$0\")/../sms_export.json}\"\nBASE_URL=\"${FINANCE_HUB_URL:-http://localhost:3001}\"\nDRY_RUN=false\n[[ \"${1:-}\" == \"--dry-run\" || \"${2:-}\" == \"--dry-run\" ]] && DRY_RUN=true\n\nif [[ ! -f \"$EXPORT_FILE\" ]]; then\n echo \"ERROR: export file not found: $EXPORT_FILE\"\n exit 1\nfi\n\ntotal=$(python3 -c \"import json; print(len(json.load(open('$EXPORT_FILE'))))\")\necho \"Importing $total SMS messages from $EXPORT_FILE → $BASE_URL\"\n$DRY_RUN && echo \"(DRY RUN — no requests will be sent)\"\n\nok=0; fail=0; idx=0\n\npython3 -c \"\nimport json, sys\nrecords = json.load(open('$EXPORT_FILE'))\nfor r in records:\n print(json.dumps({'message': r['message']}))\n\" | while IFS= read -r body; do\n idx=$((idx + 1))\n msg_preview=$(echo \"$body\" | python3 -c \"import json,sys; d=json.load(sys.stdin); print(d['message'][:60])\" 2>/dev/null || echo \"(parse error)\")\n\n if $DRY_RUN; then\n echo \"[$idx/$total] DRY: $msg_preview\"\n continue\n fi\n\n http_code=$(curl -s -o /tmp/_reimport_resp.json -w \"%{http_code}\" \\\n -X POST \"$BASE_URL/api/payments/ingest\" \\\n -H \"Content-Type: application/json\" \\\n -d \"$body\" 2>/dev/null)\n\n if [[ \"$http_code\" == \"201\" ]]; then\n echo \"[$idx/$total] OK $msg_preview\"\n ok=$((ok + 1))\n else\n resp=$(cat /tmp/_reimport_resp.json 2>/dev/null || echo \"(no response)\")\n echo \"[$idx/$total] ERR $http_code — $msg_preview\"\n echo \" $resp\"\n fail=$((fail + 1))\n fi\n\n # Rate-limit slightly to avoid hammering the server\n sleep 0.05\ndone\n\necho \"\"\necho \"Done. OK=$ok FAILED=$fail TOTAL=$total\"","role_description":"editor","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#!/usr/bin/env bash\n# Bulk re-import SMS messages from sms_export.json into finance-hub.\n# Usage: bash scripts/reimport_sms.sh [--dry-run]\n#\n# Each record is POSTed to POST /api/payments/ingest (public, no auth needed).\n# The script prints a progress line per message and a final summary.\n\nset -euo pipefail\n\nEXPORT_FILE=\"${1:-$(dirname \"$0\")/../sms_export.json}\"\nBASE_URL=\"${FINANCE_HUB_URL:-http://localhost:3001}\"\nDRY_RUN=false\n[[ \"${1:-}\" == \"--dry-run\" || \"${2:-}\" == \"--dry-run\" ]] && DRY_RUN=true\n\nif [[ ! -f \"$EXPORT_FILE\" ]]; then\n echo \"ERROR: export file not found: $EXPORT_FILE\"\n exit 1\nfi\n\ntotal=$(python3 -c \"import json; print(len(json.load(open('$EXPORT_FILE'))))\")\necho \"Importing $total SMS messages from $EXPORT_FILE → $BASE_URL\"\n$DRY_RUN && echo \"(DRY RUN — no requests will be sent)\"\n\nok=0; fail=0; idx=0\n\npython3 -c \"\nimport json, sys\nrecords = json.load(open('$EXPORT_FILE'))\nfor r in records:\n print(json.dumps({'message': r['message']}))\n\" | while IFS= read -r body; do\n idx=$((idx + 1))\n msg_preview=$(echo \"$body\" | python3 -c \"import json,sys; d=json.load(sys.stdin); print(d['message'][:60])\" 2>/dev/null || echo \"(parse error)\")\n\n if $DRY_RUN; then\n echo \"[$idx/$total] DRY: $msg_preview\"\n continue\n fi\n\n http_code=$(curl -s -o /tmp/_reimport_resp.json -w \"%{http_code}\" \\\n -X POST \"$BASE_URL/api/payments/ingest\" \\\n -H \"Content-Type: application/json\" \\\n -d \"$body\" 2>/dev/null)\n\n if [[ \"$http_code\" == \"201\" ]]; then\n echo \"[$idx/$total] OK $msg_preview\"\n ok=$((ok + 1))\n else\n resp=$(cat /tmp/_reimport_resp.json 2>/dev/null || echo \"(no response)\")\n echo \"[$idx/$total] ERR $http_code — $msg_preview\"\n echo \" $resp\"\n fail=$((fail + 1))\n fi\n\n # Rate-limit slightly to avoid hammering the server\n sleep 0.05\ndone\n\necho \"\"\necho \"Done. OK=$ok FAILED=$fail TOTAL=$total\"","depth":29,"bounds":{"left":0.13763298,"top":0.09497207,"width":0.35073137,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Design new payment-logge…, Editor Group 2","depth":28,"bounds":{"left":0.5578458,"top":0.047885075,"width":0.07912234,"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 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,"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":"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":"Sign In","depth":16,"bounds":{"left":0.9650931,"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.96675533,"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.97207445,"top":0.9856345,"width":0.013962766,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Shell Script","depth":16,"bounds":{"left":0.93916225,"top":0.98244214,"width":0.023603724,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Editor Language Status: $(copilot) No inline suggestion available, Inline suggestions","depth":16,"bounds":{"left":0.9318484,"top":0.98244214,"width":0.00731383,"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.9212101,"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.90359044,"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: 2","depth":16,"bounds":{"left":0.8796542,"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 1, Col 1","depth":16,"bounds":{"left":0.8540558,"top":0.98244214,"width":0.023936171,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"collapsed","depth":12,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Design new payment-logger and dsk-uploader hybrid app","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.97839093,"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.9890292,"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":"payments.js","depth":23,"on_screen":false,"role_description":"button","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":"ets create a new app that should be combination of payment-logger and dsk-uploader. It should have authorization via authentik (auth folder). All three folders (payment-logger, dsk-uploader and auth) are just refference these will be removed later. Auth project is separated it lives on its own. First reveiw them and see how these should be combined. It will be whole new app (also the folder name). Think very carefully of whatr these two apps do and how cold they be combined. THerer should be common db and uploader should store data the same way the /ingest does. It should be properly marked in UI if it is upload or ingest or both. FIrst think of tech stack and plan carefully.","depth":26,"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":"I'll explore all three reference projects in parallel to understand their structure before planning.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Agent:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Explore payment-logger app structure and functionality","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 /volume2/docker/finance/payments-logger directory thoroughly. I need to understand:\n1. Tech stack (frontend framework, backend framework, database)\n2. What the app does - its core purpose and features\n3. Database schema - all tables, relationships\n4. API routes - all endpoints, their purpose and request/response shapes\n5. How data flows (ingest, storage, retrieval)\n6. Any auth/middleware setup\n7. Docker/deployment setup\n8. Key files and their roles\n\nReport with: directory structure, tech stack summary, database schema details, all API endpoints listed, UI features, and how data is ingested. Be thorough on the /ingest endpoint specifically.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Agent:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Explore dsk-uploader app structure and functionality","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 /volume2/docker/finance/dsk-uploader directory thoroughly. I need to understand:\n1. Tech stack (frontend framework, backend framework, database)\n2. What the app does - its core purpose and features\n3. Database schema - all tables, relationships\n4. API routes - all endpoints, their purpose and request/response shapes\n5. How file uploads work - what files, what format, how parsed\n6. Any auth/middleware setup\n7. Docker/deployment setup\n8. Key files and their roles\n\nReport with: directory structure, tech stack summary, database schema details, all API endpoints listed, UI features, how file upload parsing works, and what data is extracted from uploads. Be very thorough about the data model and what fields are stored.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Agent:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Explore auth folder and authentik integration","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 /volume2/docker/finance/auth directory thoroughly. I need to understand:\n1. What auth system is being used (Authentik)\n2. How authentication/authorization is implemented - OAuth2, OIDC, session tokens, JWT?\n3. Middleware - how is auth enforced on routes?\n4. Any frontend auth flow - login redirect, token handling, protected routes\n5. Environment variables related to auth\n6. Docker/deployment setup for the auth service itself\n7. Any example of how other apps integrate with this auth\n\nReport with: directory structure, auth flow description, middleware code, environment variable names, and integration patterns. This is a reference for building auth into a new combined app.","depth":25,"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":"AXButton","text":"payments.js","depth":23,"on_screen":false,"role_description":"button","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":"continue","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":"Launching parallel exploration of all three reference projects.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Agent:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Explore payment-logger app structure","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 /volume2/docker/finance/payments-logger directory thoroughly. I need to understand:\n1. Full directory structure (tree)\n2. Tech stack (frontend framework, backend framework, database, etc.)\n3. What the app does - its core functionality\n4. How data is ingested (look at /ingest route especially)\n5. Database schema (what tables/collections exist)\n6. API routes and their purposes\n7. Frontend pages and components\n8. Docker setup\n9. Any auth/session handling\n\nPlease read key files: package.json files, main entry points, route files, database schema files, docker-compose.yml, and any frontend components. Be thorough - I need a complete picture to plan a new combined app.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Agent:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Explore dsk-uploader app structure","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 /volume2/docker/finance/dsk-uploader directory thoroughly. I need to understand:\n1. Full directory structure (tree)\n2. Tech stack (frontend framework, backend framework, database, etc.)\n3. What the app does - its core functionality\n4. How file uploads work (what format, what processing happens)\n5. Database schema (what tables/collections exist)\n6. API routes and their purposes\n7. Frontend pages and components\n8. Docker setup\n9. Any auth/session handling\n\nPlease read key files: package.json files, main entry points, route files, database schema files, docker-compose.yml, and any frontend components. Be thorough - I need a complete picture to plan a new combined app.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Agent:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Explore auth project structure","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 /volume2/docker/finance/auth directory thoroughly. I need to understand:\n1. Full directory structure (tree)\n2. What authentication system is used (authentik integration details)\n3. How OAuth/OIDC flow works\n4. Any middleware or helper functions for protecting routes\n5. Session management approach\n6. How frontend handles auth state\n7. Any example of how other apps integrate with this auth system\n8. Docker setup and environment variables\n\nPlease read all files carefully - this auth system will be integrated into a new combined app. I need to understand exactly how to use it.","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 a complete picture of all three. Let me design the plan.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Agent:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Design combined app architecture","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Design a detailed implementation plan for a new combined web app that merges two existing applications. Here is full context:\n\n---\n\n## App 1: payments-logger (Node.js)\n- **Purpose**: Ingest Bulgarian bank SMS → parse → store in PostgreSQL → review/tag/notify in React UI\n- **Stack**: Node.js 20 + Express + Prisma 5 + PostgreSQL 16 + React 18 + Vite + Tailwind CSS\n- **Auth**: Custom JWT (bcryptjs + jose), tokens in localStorage\n- **Ingest**: POST /api/payments/ingest (public) — SMS text OR structured JSON (Apple Wallet)\n- **Schema** (PostgreSQL via Prisma):\n - `payments` table: id, raw_message, date, type (POS/ATM/INTERNET/ECOM/P2P/WALLET), card, recipient, amount, balance, status (UNPROCESSED/SENT/SKIPPED), notifyPhone, notifiedAt, created_at, updated_at\n - `tags` table: id, name, color — M2M with payments via `_PaymentToTag`\n - `users` table: id, username, hashed_password (this will be REMOVED)\n- **UI**: Single-page React app — PaymentTable (sortable, filterable, taggable), FilterBar, status actions (send/skip), notification system\n- **Parser** (backend/src/parser.js): Regex parser for Bulgarian DSK Bank SMS, extracts date/time (DD/MM/YYYY HH:MM), card mask, transaction type, recipient, amount, balance\n\n## App 2: dsk-uploader (Python/Flask)\n- **Purpose**: Upload DSK bank CSV exports → parse/normalize → upload to Notion database\n- **Stack**: Python 3.11 + Flask + Pandas + Custom Notion SDK + Bootstrap 5\n- **Auth**: None (open)\n- **CSV format** (DSK Bank Bulgarian format, columns):\n - `Дата` (date, DD.MM.YYYY)\n - `Вид на трансакцията` (transaction type, Bulgarian)\n - `Основание` (reason/description — contains card number regex: `^\\d{6}x{6}\\d{4}$`)\n - `Дебит BGN` (debit amount, may be empty)\n - `Кредит BGN` (credit amount, may be empty)\n - `Наредител/Получател` (orderer/recipient name)\n - `Номер сметка на наредителя / получателя` (account number)\n- **Processing**: merge multiple CSVs, normalize dates, extract card numbers from reason via regex, auto-generate tags (keyword heuristics: ЗАПЛАТА→Salary, NETFLIX→Subscriptions, etc.), filter internal transfers\n- **Output**: Notion database pages (this will be REPLACED with local PostgreSQL)\n\n## App 3: auth (Authentik)\n- **Mode**: Proxy mode via NPM (forward auth)\n- **How it works**: NPM intercepts all requests, calls Authentik outpost's auth endpoint. On success, NPM injects headers into proxied request:\n - `X-authentik-username` \n - `X-authentik-email`\n - `X-authentik-groups`\n- **No code integration needed** in the app itself — just trust these headers from NPM\n- **Logout**: Redirect user to `/outpost.goauthentik.io/sign_out`\n\n---\n\n## What the New Combined App Must Do\n\n1. **Single PostgreSQL database** for all transactions\n2. **SMS Ingest** (public endpoint) — same as payments-logger /ingest, source=INGEST\n3. **CSV Upload** (authenticated) — parse DSK CSV files, store transactions with source=UPLOAD into the same DB schema\n4. **Unified UI** — show all payments in one table regardless of source\n5. **Source indicator** in UI — badge showing \"INGEST\", \"UPLOAD\", or \"BOTH\" (if duplicate detection added)\n6. **Source filter** in FilterBar — filter by All/Ingest/Upload\n7. **Authentik auth** — remove custom JWT entirely; trust X-authentik-* headers from NPM\n8. **All existing payments-logger features**: tagging, send notification, skip, status tracking, filters, sorting, pagination\n9. **Remove Notion dependency entirely** — all data stays in local PostgreSQL\n\n---\n\n## Technical Constraints\n\n- Keep Node.js backend (not Python) — extend payments-logger's stack\n- CSV parsing: use `csv-parse` npm package (handles encoding, streaming)\n- File upload: use `multer` npm middleware\n- Auth middleware: read X-authentik-username header, 401 if missing (but /api/payments/ingest stays public)\n- Add `source` enum field (INGEST/UPLOAD) to payments schema\n- Add `currency` field (EUR for SMS ingest, BGN for CSV uploads) — or just store as-is\n- Remove `users` table from schema\n\n---\n\n## Please Design\n\n1. Complete folder structure for the new app (suggest name: \"finance-hub\" or similar — note this is a placeholder, user will confirm)\n2. Prisma schema with new fields (`source`, `currency`)\n3. All backend API routes\n4. CSV parser design in Node.js (port of the Python logic)\n5. Authentik auth middleware\n6. Frontend component structure (React) — what's reused from payments-logger, what's new\n7. Docker Compose setup\n8. Environment variables needed\n9. Step-by-step implementation order\n10. Verification checklist\n\nBe specific about file paths and code structure. This will be used to write actual implementation code.","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":"Good plan. Let me ask the one thing I need before writing the final plan.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskUserQuestion","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"User has answered your questions: \"What should the new combined app be called? This will be the folder name under /volume2/docker/finance/ and the app branding.\"=\"finance-hub\". You can now continue with the user's answers in mind.","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":"Writing the final plan now.","depth":23,"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":"Write","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"ets-create-a-new-generic-sun.md","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"ets-create-a-new-generic-sun.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"326 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# finance-hub — Implementation Plan\n\n## Context\n\nTwo separate finance apps exist as references and will be retired:\n- **payments-logger** (Node.js/React): Ingests Bulgarian bank SMS notifications, stores payments in PostgreSQL, provides a review/tag/notify UI.\n- **dsk-uploader** (Python/Flask): Uploads DSK bank CSV exports, parses them, sends to Notion.\n\nThe new app **finance-hub** (`/volume2/docker/finance/finance-hub/`) replaces both with a single unified system: all transactions (SMS-ingested and CSV-uploaded) land in one PostgreSQL database and one React UI. Authentication is delegated entirely to Authentik (proxy mode via NPM — no custom JWT).\n\n---\n\n## Tech Stack\n\n| Layer | Choice | Rationale |\n|-------|--------|-----------|\n| Backend | Node.js 20 + Express + Prisma 5 | Extends payments-logger; no Python needed |\n| CSV parsing | `csv-parse` + `iconv-lite` | Handles Bulgarian cp1251 encoding, RFC4180 quoted fields |\n| File upload | `multer` (memory storage) | Bank CSVs are small (<500 KB), no disk cleanup needed |\n| Database | PostgreSQL 16 | Same as payments-logger |\n| Frontend | React 18 + Vite + Tailwind CSS + Lucide React | Same as payments-logger |\n| Auth | Authentik proxy via NPM headers | No custom JWT; removes users table entirely |\n| Container | Docker Compose | Same pattern as both reference apps |\n\n**Removed vs payments-logger:** `bcryptjs`, `jose`, `users` table, login form, JWT storage. \n**Removed vs dsk-uploader:** Python/Flask, Pandas, Notion SDK, all Notion references. \n**Added:** `csv-parse`, `iconv-lite`, `multer`, `source` + `currency` fields, `UploadPanel` component.\n\n---\n\n## Folder Structure\n\n```\n/volume2/docker/finance/finance-hub/\n├── docker-compose.yml\n├── .env\n├── .env.example\n├── .gitignore\n├── backend/\n│ ├── Dockerfile\n│ ├── package.json\n│ ├── prisma/\n│ │ ├── schema.prisma\n│ │ └── migrations/\n│ │ ├── migration_lock.toml\n│ │ └── 20260508_init/\n│ │ └── migration.sql\n│ └── src/\n│ ├── index.js ← entry point (Authentik middleware wired here)\n│ ├── auth.js ← Authentik header middleware (replaces JWT auth)\n│ ├── parser.js ← SMS parser (copy verbatim from payments-logger)\n│ ├── csvParser.js ← NEW: DSK CSV parser (port of Python dskuploader.py)\n│ └── routes/\n│ ├── payments.js ← existing routes + source/currency additions\n│ └── upload.js ← NEW: POST /api/upload/csv\n└── frontend/\n ├── Dockerfile\n ├── package.json\n ├── vite.config.js\n ├── tailwind.config.js\n ├── postcss.config.js\n ├── index.html\n └── src/\n ├── main.jsx ← remove AuthProvider wrapper\n ├── index.css\n ├── App.jsx ← remove auth state, add Upload tab toggle\n └── components/\n ├── FilterBar.jsx ← add source filter select\n ├── PaymentTable.jsx ← add Source badge column + currency display\n ├── PaymentCard.jsx ← minor source badge addition\n ├── PaymentList.jsx ← unchanged\n └── UploadPanel.jsx ← NEW: drag-and-drop CSV upload UI\n```\n\n---\n\n## Database Schema (Prisma)\n\nFile: `backend/prisma/schema.prisma`\n\n```prisma\ngenerator client {\n provider = \"prisma-client-js\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n url = env(\"DATABASE_URL\")\n}\n\nmodel Payment {\n id Int @id @default(autoincrement())\n rawMessage String @map(\"raw_message\")\n date DateTime?\n type String?\n card String?\n recipient String?\n amount Float?\n currency String? @default(\"EUR\")\n balance Float?\n source Source @default(INGEST)\n status Status @default(UNPROCESSED)\n tags Tag[]\n notifiedAt DateTime? @map(\"notified_at\")\n notifyPhone String? @map(\"notify_phone\")\n debitBgn Float? @map(\"debit_bgn\")\n creditBgn Float? @map(\"credit_bgn\")\n transactionType String? @map(\"transaction_type\")\n payerAccount String? @map(\"payer_account\")\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n\n @@map(\"payments\")\n}\n\nmodel Tag {\n id Int @id @default(autoincrement())\n name String @unique\n color String @default(\"#6b7280\")\n payments Payment[]\n\n @@map(\"tags\")\n}\n\nenum Status { UNPROCESSED SENT SKIPPED }\nenum Source { INGEST UPLOAD }\n```\n\n**Key decisions:**\n- No `User` model — Authentik owns identity.\n- `currency`: `EUR` for SMS ingest, `BGN` for CSV uploads.\n- `debitBgn`, `creditBgn`, `transactionType`, `payerAccount`: nullable CSV-only columns; INGEST rows store nulls. Avoids a union query for the unified list view.\n- `balance` is always null for CSV rows (DSK export does not include running balance).\n- Fresh consolidated migration — no data migration from reference apps required.\n\n---\n\n## API Routes\n\n| Method | Path | Auth | Description |\n|--------|------|------|-------------|\n| GET | /api/health | public | Health check |\n| POST | /api/payments/ingest | public | SMS or structured ingest (source=INGEST) |\n| GET | /api/payments | required | List with filters/sort/pagination (+ source filter) |\n| GET | /api/payments/meta/tags | required | All tags |\n| GET | /api/payments/meta/filters | required | Filter options incl. `sources` array |\n| GET | /api/payments/:id | required | Single payment |\n| PATCH | /api/payments/:id | required | Update status |\n| DELETE | /api/payments/:id | required | Delete |\n| POST | /api/payments/:id/send | required | Send notification |\n| POST | /api/payments/:id/skip | required | Skip |\n| POST | /api/payments/:id/tags | required | Add/upsert tag |\n| DELETE | /api/payments/:id/tags/:tagId | required | Remove tag |\n| POST | /api/upload/csv | required | DSK CSV file upload (source=UPLOAD) |\n\n---\n\n## Key Implementation Details\n\n### auth.js (replaces entire old auth module)\n```js\nconst PUBLIC_PATHS = new Set(['/api/health', '/api/payments/ingest']);\n\nfunction authentikMiddleware(req, res, next) {\n if (PUBLIC_PATHS.has(req.path)) return next();\n const username = req.headers['x-authentik-username'];\n if (!username) return res.status(401).json({ error: 'Unauthorized' });\n req.user = {\n username,\n email: req.headers['x-authentik-email'] || null,\n groups: (req.headers['x-authentik-groups'] || '').split(',').map(g => g.trim()).filter(Boolean),\n };\n next();\n}\nmodule.exports = { authentikMiddleware };\n```\n\n### csvParser.js (port of dskuploader.py)\n- `iconv-lite` decodes buffer as cp1251 (DSK Bank export encoding), falls back to UTF-8\n- `csv-parse` parses the decoded text with `columns: true`\n- Columns: `Дата`, `Вид на трансакцията`, `Основание`, `Дебит BGN`, `Кредит BGN`, `Наредител/Получател`, `Номер сметка на наредителя / получателя`\n- Card extraction: regex `/^\\d{6}x{6}\\d{4}$/` on first token of `Основание`\n- Skips rows where `Вид на трансакцията === 'ТРАНСФЕР СОБСТВЕНИ СМЕТКИ'`\n- Auto-tags via keyword rules (ЗАПЛАТА→Salary, LIDL→Groceries, NETFLIX→Subscriptions, etc.) — same logic as Python `generate_tags()`\n- Returns `{ rows: PaymentData[], skipped: number, errors: string[] }`\n\n### payments.js changes from payments-logger\n1. Add `source: 'INGEST'` and `currency` to the `/ingest` create call\n2. Add `source` to the `GET /` where clause filter\n3. Add `sources` to `meta/filters` response\n4. Currency-aware amount formatting in notification message\n5. Remove all JWT/auth references (no `/auth/register`, `/auth/login`)\n\n### upload.js (new)\n- `multer` memory storage, max 10 files × 10 MB\n- Calls `parseDskCsv(buffer)` per file\n- Upserts tags via `prisma.tag.upsert` then connects\n- Returns `{ imported, skipped, errors, payments[] }`\n\n### Frontend changes\n- **Delete**: `auth.js`, `AuthProvider.jsx`\n- **main.jsx**: Remove `<AuthProvider>` wrapper\n- **App.jsx**: Replace `authFetch` with plain `fetch` (Authentik session cookie travels automatically); logout → `window.location.href = '/outpost.goauthentik.io/sign_out'`; add \"Payments\" / \"Upload CSV\" tab toggle\n- **FilterBar.jsx**: Add source `<select>` (All / SMS Ingest / CSV Upload); widen grid to 5 cols\n- **PaymentTable.jsx**: Add `Source` column with `SMS` (indigo) / `CSV` (emerald) badge; show `${amount} ${currency}` in amount cell\n- **UploadPanel.jsx** (new): Drag-and-drop zone + file list + import button + result summary with error accordion; calls `POST /api/upload/csv` with `FormData`\n\n---\n\n## Docker Compose\n\n```yaml\nservices:\n db:\n image: postgres:16-alpine\n environment: { POSTGRES_USER: finance, POSTGRES_PASSWORD: ${DB_PASSWORD}, POSTGRES_DB: finance_hub }\n volumes: [pgdata:/var/lib/postgresql/data]\n healthcheck: { test: pg_isready -U finance -d finance_hub, interval: 5s }\n\n backend:\n build: ./backend\n environment:\n DATABASE_URL: postgresql://finance:${DB_PASSWORD}@db:5432/finance_hub\n PORT: \"3001\"\n NOTIFIER_URL: ${NOTIFIER_URL}\n NOTIFIER_CHANNEL: ${NOTIFIER_CHANNEL:-viber}\n NOTIFY_DEFAULT_PHONE: ${NOTIFY_DEFAULT_PHONE}\n TZ: ${TZ:-Europe/Sofia}\n ports: [\"${BACKEND_PORT:-3001}:3001\"]\n depends_on: { db: { condition: service_healthy } }\n\n frontend:\n build: ./frontend\n ports: [\"${FRONTEND_PORT:-5175}:5173\"]\n depends_on: [backend]\n\nvolumes: { pgdata: }\n```\n\n**NPM setup:** Frontend port proxied through Authentik forward auth. Backend port exposed separately (unprotected) so the public `/api/payments/ingest` remains reachable by iOS Shortcuts / SMS gateways without login.\n\n---\n\n## Environment Variables (.env)\n\n```bash\nDB_PASSWORD=change_me\nNOTIFIER_URL=https://notifier.lakylak.xyz\nNOTIFIER_CHANNEL=viber\nNOTIFY_DEFAULT_PHONE=+359000000000\nTZ=Europe/Sofia\nBACKEND_PORT=3001\nFRONTEND_PORT=5175\n```\n\nRemoved vs payments-logger: `JWT_SECRET`, `JWT_EXPIRE_MINUTES`.\n\n---\n\n## Implementation Order\n\n1. Create folder structure and write `docker-compose.yml`, `.env.example`, `.gitignore`\n2. Write `backend/prisma/schema.prisma` and migration SQL\n3. Write `backend/package.json` (add `csv-parse`, `iconv-lite`, `multer`; remove `bcryptjs`, `jose`)\n4. Write `backend/Dockerfile`\n5. Write `backend/src/auth.js` (Authentik middleware)\n6. Copy `backend/src/parser.js` verbatim from payments-logger\n7. Write `backend/src/csvParser.js` (Python port)\n8. Write `backend/src/routes/upload.js`\n9. Write `backend/src/routes/payments.js` (from payments-logger + 5 changes listed above)\n10. Write `backend/src/index.js`\n11. Copy frontend base from payments-logger; delete `auth.js` + `AuthProvider.jsx`\n12. Update `main.jsx`, `App.jsx`, `FilterBar.jsx`, `PaymentTable.jsx`\n13. Write `frontend/src/components/UploadPanel.jsx`\n14. Update `frontend/vite.config.js`\n15. `docker compose build && docker compose up -d`\n16. Run verification checklist\n\n---\n\n## Verification\n\n**Schema**\n- `payments` table has `source`, `currency`, `debit_bgn`, `credit_bgn`, `transaction_type`, `payer_account`\n- No `users` table; `Source` enum exists\n\n**Auth**\n- `GET /api/payments` → 401 without `x-authentik-username` header\n- `POST /api/payments/ingest` → 201 without any header\n- `curl -H \"x-authentik-username: test\" localhost:3001/api/payments` → 200\n\n**SMS Ingest**\n- DSK POS SMS → `source=INGEST`, `currency=EUR`, correct amount/card/recipient\n- Apple Wallet structured body → `type=WALLET`, `source=INGEST`\n- Rate limiter → 429 after 200 req/min\n\n**CSV Upload**\n- Single DSK CSV → rows with `source=UPLOAD`, `currency=BGN`\n- Multiple CSVs in one request → all merged\n- `ТРАНСФЕР СОБСТВЕНИ СМЕТКИ` rows counted in `skipped`, not imported\n- Card regex match from `Основание` column\n- Auto-tags applied (ЗАПЛАТА→Salary, LIDL→Groceries)\n- cp1251 file imports correctly\n\n**UI**\n- Source badge visible in payment table (SMS indigo, CSV emerald)\n- Source dropdown in FilterBar filters correctly\n- Amount shows correct currency per row\n- Upload Panel: drag-and-drop works, result summary shows counts\n- Logout redirects to Authentik sign_out\n- No login form shown (Authentik handles it at NPM level)\n- Tags, send, skip, delete all still work\n\n## Reference Files\n\n- `/volume2/docker/finance/payments-logger/backend/src/routes/payments.js`\n- `/volume2/docker/finance/payments-logger/backend/src/parser.js`\n- `/volume2/docker/finance/payments-logger/backend/src/index.js`\n- `/volume2/docker/finance/payments-logger/backend/src/auth.js`\n- `/volume2/docker/finance/payments-logger/backend/prisma/schema.prisma`\n- `/volume2/docker/finance/payments-logger/frontend/src/App.jsx`\n- `/volume2/docker/finance/payments-logger/frontend/src/components/PaymentTable.jsx`\n- `/volume2/docker/finance/payments-logger/frontend/src/components/FilterBar.jsx`\n- `/volume2/docker/finance/dsk-uploader/dskuploader.py`\n- `/volume2/docker/finance/auth/docker-compose.yml`","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Claude’s Plan","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"ets-create-a-new-generic-sun.md","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"ets-create-a-new-generic-sun.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Stayed in plan mode","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":"Good question. Here's the full breakdown:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Backend Tech Stack — Options","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Backend Tech Stack — Options","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Option A: Node.js + Express + Prisma (my recommendation)","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Option A: Node.js + Express + Prisma (my recommendation)","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Why:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"payments-logger is already Node.js/Express/Prisma. The new app is 80% payments-logger with CSV upload added on top. Keeping the same stack means:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Copy","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"parser.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"verbatim, zero rewrite","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Copy the entire","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"routes/payments.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"with minimal edits","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Same Prisma schema workflow, same migrations, same Docker image","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"The CSV parsing logic (the only Python-specific thing) ports cleanly to","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"csv-parse","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— it's just regex + string manipulation, nothing pandas-specific","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Trade-off:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Have to port the Python CSV parsing to JS. It's ~150 lines and mostly string manipulation — straightforward.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Option B: Python + FastAPI + SQLAlchemy","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Option B: Python + FastAPI + SQLAlchemy","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Rewrite everything in Python. dsk-uploader is Python, so CSV parsing is already done.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Pro:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Keep the dsk-uploader CSV logic as-is (no porting). Python has better data science libraries if you later add analytics.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Con:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Lose the entire payments-logger backend (routes, parser, Prisma schema) — full rewrite. FastAPI + SQLAlchemy is a different mental model than Express + Prisma. Frontend stays React anyway, so the stack split doesn't simplify anything.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Verdict:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"More work overall, gains almost nothing.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Option C: Hybrid microservices (Node.js backend + Python CSV service)","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Option C: Hybrid microservices (Node.js backend + Python CSV service)","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Keep Node.js as the main API, add a separate Python FastAPI service just for CSV parsing. They share the DB.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Pro:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Zero porting — Python CSV code used as-is.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Con:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Two backend services to maintain, deploy, and keep in sync. Inter-service HTTP calls. Two Dockerfiles. For ~150 lines of CSV logic, this is massively over-engineered.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Verdict:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Not worth it.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Option D: Python + Flask (exactly like dsk-uploader)","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Option D: Python + Flask (exactly like dsk-uploader)","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Extend dsk-uploader into a full payments app.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Pro:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Pandas for CSV, no porting.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Con:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Jinja2 templates instead of React (or add React separately). Would need to reimplement the entire payments-logger (SMS parser, notification system, tag management, pagination/filtering). Flask's Jinja templating is far less capable than the existing React UI. The React frontend is the stronger UI foundation.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Verdict:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Worst of all options — rebuild the harder parts (UI, SMS parser, notification) for no gain.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Summary","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Summary","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Option","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CSV porting effort","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"App rewrite effort","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Result quality","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"A (Node.js)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Medium (150 lines)","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Minimal","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Best","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"B (Python FastAPI)","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"None","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"High (full backend)","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Worse","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"C (Hybrid)","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"None","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Low + infra overhead","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Overkill","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"D (Python Flask)","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"None","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Very high","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Worst","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Option","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"A (Node.js)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"B (Python FastAPI)","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"C (Hybrid)","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"D (Python Flask)","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CSV porting effort","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Medium (150 lines)","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"None","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"None","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"None","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"App rewrite effort","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Minimal","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"High (full backend)","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Low + infra overhead","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Very high","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Result quality","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Best","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Worse","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Overkill","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Worst","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Option","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CSV porting effort","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"App rewrite effort","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Result quality","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"The CSV parser port (the only cost of Option A) is a one-time ~150 line exercise. Everything else in the plan reuses payments-logger code directly. That's why Node.js is the clear winner here.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Want to adjust the stack, or shall I proceed with Option A?","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":"ok sounds good. Implement all you suggested","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":"Starting implementation. Let me first read all the reference files I'll need to copy from.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"parser.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"parser.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":"AXStaticText","text":",","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":"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":"FilterBar.jsx","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"FilterBar.jsx","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"PaymentTable.jsx","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"PaymentTable.jsx","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 and the Dockerfile from payments-logger.","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":"index.css","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"index.css","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":"Dockerfile","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Dockerfile","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Dockerfile","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Dockerfile","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":"tailwind.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":"tailwind.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":"postcss.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":"postcss.config.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":"index.html","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"index.html","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"dskuploader.py","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"dskuploader.py","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 also grab the remaining frontend components.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"PaymentCard.jsx","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"PaymentCard.jsx","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"PaymentList.jsx","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"PaymentList.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":"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":"Good, I have everything I need. Let me set up the todo list and start building.","depth":23,"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":"Update Todos","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Create folder structure and root config files","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend Prisma schema and migration","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend package.json and Dockerfile","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend src files (auth, parser, csvParser, index)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend routes (payments.js, upload.js)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write frontend config files","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write frontend React components","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Build and verify with docker compose","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Create finance-hub directory structure","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"mkdir -p /volume2/docker/finance/finance-hub/backend/src/routes \\\n /volume2/docker/finance/finance-hub/backend/prisma/migrations/20260508_init \\\n /volume2/docker/finance/finance-hub/frontend/src/components && echo \"done\"","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":"done","depth":24,"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":"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":"45 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"version: '3.8'\n\nservices:\n db:\n image: postgres:16-alpine\n restart: unless-stopped\n environment:\n POSTGRES_USER: finance\n POSTGRES_PASSWORD: ${DB_PASSWORD}\n POSTGRES_DB: finance_hub\n volumes:\n - pgdata:/var/lib/postgresql/data\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U finance -d finance_hub\"]\n interval: 5s\n timeout: 5s\n retries: 5\n\n backend:\n build: ./backend\n restart: unless-stopped\n environment:\n DATABASE_URL: postgresql://finance:${DB_PASSWORD}@db:5432/finance_hub\n PORT: \"3001\"\n NOTIFIER_URL: ${NOTIFIER_URL}\n NOTIFIER_CHANNEL: ${NOTIFIER_CHANNEL:-viber}\n NOTIFY_DEFAULT_PHONE: ${NOTIFY_DEFAULT_PHONE}\n TZ: ${TZ:-Europe/Sofia}\n ports:\n - \"${BACKEND_PORT:-3001}:3001\"\n depends_on:\n db:\n condition: service_healthy\n\n frontend:\n build: ./frontend\n restart: unless-stopped\n ports:\n - \"${FRONTEND_PORT:-5175}:5173\"\n depends_on:\n - backend\n\nvolumes:\n pgdata:","depth":25,"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":".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":"15 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# Database\nDB_PASSWORD=change_me_strong_password\n\n# Notifier service (for SMS payment notifications)\nNOTIFIER_URL=https://notifier.lakylak.xyz\nNOTIFIER_CHANNEL=viber\nNOTIFY_DEFAULT_PHONE=+359000000000\n\n# Timezone (used by SMS parser for Bulgarian bank timestamps)\nTZ=Europe/Sofia\n\n# Ports (optional — defaults shown)\nBACKEND_PORT=3001\nFRONTEND_PORT=5175","depth":25,"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":".gitignore","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":".gitignore","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"5 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".env\nnode_modules/\ndist/\n*.log","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update Todos","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Create folder structure and root config files","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend Prisma schema and migration","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend package.json and Dockerfile","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend src files (auth, parser, csvParser, index)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend routes (payments.js, upload.js)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write frontend config files","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write frontend React components","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Build and verify with docker compose","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":"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":"54 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"generator client {\n provider = \"prisma-client-js\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n url = env(\"DATABASE_URL\")\n}\n\nmodel Payment {\n id Int @id @default(autoincrement())\n rawMessage String @map(\"raw_message\")\n date DateTime?\n type String?\n card String?\n recipient String?\n amount Float?\n currency String? @default(\"EUR\")\n balance Float?\n source Source @default(INGEST)\n status Status @default(UNPROCESSED)\n tags Tag[]\n notifiedAt DateTime? @map(\"notified_at\")\n notifyPhone String? @map(\"notify_phone\")\n debitBgn Float? @map(\"debit_bgn\")\n creditBgn Float? @map(\"credit_bgn\")\n transactionType String? @map(\"transaction_type\")\n payerAccount String? @map(\"payer_account\")\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n\n @@map(\"payments\")\n}\n\nmodel Tag {\n id Int @id @default(autoincrement())\n name String @unique\n color String @default(\"#6b7280\")\n payments Payment[]\n\n @@map(\"tags\")\n}\n\nenum Status {\n UNPROCESSED\n SENT\n SKIPPED\n}\n\nenum Source {\n INGEST\n UPLOAD\n}","depth":25,"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":"migration.sql","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"migration.sql","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"55 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-- CreateEnum\nCREATE TYPE \"Status\" AS ENUM ('UNPROCESSED', 'SENT', 'SKIPPED');\nCREATE TYPE \"Source\" AS ENUM ('INGEST', 'UPLOAD');\n\n-- CreateTable\nCREATE TABLE \"payments\" (\n \"id\" SERIAL PRIMARY KEY,\n \"raw_message\" TEXT NOT NULL,\n \"date\" TIMESTAMP(3),\n \"type\" TEXT,\n \"card\" TEXT,\n \"recipient\" TEXT,\n \"amount\" DOUBLE PRECISION,\n \"currency\" TEXT DEFAULT 'EUR',\n \"balance\" DOUBLE PRECISION,\n \"source\" \"Source\" NOT NULL DEFAULT 'INGEST',\n \"status\" \"Status\" NOT NULL DEFAULT 'UNPROCESSED',\n \"notified_at\" TIMESTAMP(3),\n \"notify_phone\" TEXT,\n \"debit_bgn\" DOUBLE PRECISION,\n \"credit_bgn\" DOUBLE PRECISION,\n \"transaction_type\" TEXT,\n \"payer_account\" TEXT,\n \"created_at\" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,\n \"updated_at\" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP\n);\n\n-- CreateTable\nCREATE TABLE \"tags\" (\n \"id\" SERIAL PRIMARY KEY,\n \"name\" TEXT NOT NULL,\n \"color\" TEXT NOT NULL DEFAULT '#6b7280'\n);\n\n-- CreateUniqueIndex\nCREATE UNIQUE INDEX \"tags_name_key\" ON \"tags\"(\"name\");\n\n-- CreateTable (M2M join)\nCREATE TABLE \"_PaymentToTag\" (\n \"A\" INTEGER NOT NULL,\n \"B\" INTEGER NOT NULL,\n CONSTRAINT \"_PaymentToTag_AB_pkey\" PRIMARY KEY (\"A\", \"B\")\n);\n\nCREATE INDEX \"_PaymentToTag_B_index\" ON \"_PaymentToTag\"(\"B\");\n\n-- AddForeignKey\nALTER TABLE \"_PaymentToTag\"\n ADD CONSTRAINT \"_PaymentToTag_A_fkey\"\n FOREIGN KEY (\"A\") REFERENCES \"payments\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\nALTER TABLE \"_PaymentToTag\"\n ADD CONSTRAINT \"_PaymentToTag_B_fkey\"\n FOREIGN KEY (\"B\") REFERENCES \"tags\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;","depth":25,"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":"migration_lock.toml","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"migration_lock.toml","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"4 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# Please do not edit this file manually\n# It should be added in your version-control system (e.g., Git)\nprovider = \"postgresql\"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update Todos","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Create folder structure and root config files","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend Prisma schema and migration","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend package.json and Dockerfile","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend src files (auth, parser, csvParser, index)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend routes (payments.js, upload.js)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write frontend config files","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write frontend React components","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Build and verify with docker compose","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":"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":"26 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"{\n \"name\": \"finance-hub-backend\",\n \"version\": \"1.0.0\",\n \"main\": \"src/index.js\",\n \"scripts\": {\n \"start\": \"node src/index.js\",\n \"dev\": \"nodemon src/index.js\",\n \"prisma:generate\": \"prisma generate\",\n \"prisma:migrate\": \"prisma migrate deploy\"\n },\n \"dependencies\": {\n \"@prisma/client\": \"^5.22.0\",\n \"cors\": \"^2.8.5\",\n \"csv-parse\": \"^5.5.6\",\n \"express\": \"^4.21.1\",\n \"express-rate-limit\": \"^7.4.0\",\n \"iconv-lite\": \"^0.6.3\",\n \"morgan\": \"^1.10.0\",\n \"multer\": \"^1.4.5-lts.1\"\n },\n \"devDependencies\": {\n \"nodemon\": \"^3.1.7\",\n \"prisma\": \"^5.22.0\"\n }\n}","depth":25,"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":"Dockerfile","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Dockerfile","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"18 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FROM node:20-alpine\n\nRUN apk add --no-cache openssl\n\nWORKDIR /app\n\nCOPY package.json package-lock.json* ./\nRUN npm install\n\nCOPY prisma ./prisma\nRUN npx prisma generate\n\nCOPY src ./src\n\nEXPOSE 3001\n\nCMD [\"sh\", \"-c\", \"npx prisma migrate deploy && node src/index.js\"]","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update Todos","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Create folder structure and root config files","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend Prisma schema and migration","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend package.json and Dockerfile","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend src files (auth, parser, csvParser, index)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend routes (payments.js, upload.js)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write frontend config files","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write frontend React components","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Build and verify with docker compose","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":"27 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"const PUBLIC_PATHS = new Set([\n '/api/health',\n '/api/payments/ingest',\n]);\n\nfunction authentikMiddleware(req, res, next) {\n if (PUBLIC_PATHS.has(req.path)) return next();\n\n const username = req.headers['x-authentik-username'];\n if (!username) {\n return res.status(401).json({ error: 'Unauthorized — missing Authentik session' });\n }\n\n req.user = {\n username,\n email: req.headers['x-authentik-email'] || null,\n groups: (req.headers['x-authentik-groups'] || '')\n .split(',')\n .map(g => g.trim())\n .filter(Boolean),\n };\n\n next();\n}\n\nmodule.exports = { authentikMiddleware };","depth":25,"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":"parser.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"parser.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"104 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/**\n * Parses SMS payment messages from Bulgarian banks (DSK Bank, etc.)\n *\n * Supported formats:\n *\n * POS / INTERNET / ECOM / P2P payment:\n * DSK Bank. Na DD/MM/YYYY v HH:MM sa plateni AMOUNT CURRENCY s karta CARD na POS s adres: RECIPIENT. Nalichni: BALANCE CURRENCY.\n *\n * ATM withdrawal:\n * DSK Bank. Na DD/MM/YYYY v HH:MM sa iztegleni AMOUNT CURRENCY s karta CARD ot ATM s adres: RECIPIENT. Nalichni: BALANCE CURRENCY.\n *\n * ATM utility payment (amount may include fee as AMOUNT/FEE):\n * DSK Bank. Na DD/MM/YYYY v HH:MM sa plateni AMOUNT CURRENCY/FEE CURRENCY s karta CARD na ATM s adres:RECIPIENT. Nalichni: BALANCE CURRENCY.\n */\n\nconst LOCAL_TZ = process.env.TZ || 'Europe/Sofia';\n\n/**\n * Convert a local-timezone date/time to a UTC Date object.\n * Uses Intl to resolve the actual UTC offset (DST-aware).\n */\nfunction localToUtc(year, month, day, hour, minute) {\n const naive = new Date(Date.UTC(year, month - 1, day, hour, minute, 0));\n\n const formatter = new Intl.DateTimeFormat('en-US', {\n timeZone: LOCAL_TZ,\n year: 'numeric', month: '2-digit', day: '2-digit',\n hour: '2-digit', minute: '2-digit', second: '2-digit',\n hour12: false,\n });\n\n const parts = {};\n formatter.formatToParts(naive).forEach(p => { parts[p.type] = p.value; });\n\n const localAtNaive = new Date(Date.UTC(\n parseInt(parts.year), parseInt(parts.month) - 1, parseInt(parts.day),\n parseInt(parts.hour) % 24, parseInt(parts.minute), parseInt(parts.second),\n ));\n\n const offsetMs = localAtNaive.getTime() - naive.getTime();\n return new Date(Date.UTC(year, month - 1, day, hour, minute, 0) - offsetMs);\n}\n\nfunction parsePaymentSms(message) {\n const result = {\n rawMessage: message,\n date: null,\n type: null,\n card: null,\n recipient: null,\n amount: null,\n balance: null,\n };\n\n // Date and time: \"Na DD/MM/YYYY v HH:MM\"\n const dateMatch = message.match(/Na (\\d{2})\\/(\\d{2})\\/(\\d{4}) v (\\d{2}):(\\d{2})/i);\n if (dateMatch) {\n const [, day, month, year, hour, minute] = dateMatch;\n result.date = localToUtc(\n parseInt(year), parseInt(month), parseInt(day),\n parseInt(hour), parseInt(minute),\n );\n }\n\n // Card mask: \"s karta 400915***4447\" or \"s karta 483890***7162\"\n const cardMatch = message.match(/s karta\\s+([\\d*]+)/i);\n if (cardMatch) {\n result.card = cardMatch[1];\n }\n\n // Transaction type: supports both prepositions\n // \"na POS\" / \"na ATM\" / \"na INTERNET\" etc. (payment)\n // \"ot ATM\" (withdrawal)\n const typeMatch = message.match(/(?:na|ot)\\s+(POS|ATM|INTERNET|ECOM|P2P)\\b/i);\n if (typeMatch) {\n result.type = typeMatch[1].toUpperCase();\n }\n\n // Recipient address: \"s adres: MERCHANT\" or \"s adres:MERCHANT\" (no space variant)\n const recipientMatch = message.match(/s adres:\\s*([^.]+)\\./i);\n if (recipientMatch) {\n result.recipient = recipientMatch[1].trim();\n }\n\n // Amount: handles both verbs and the AMOUNT/FEE suffix format\n // \"sa plateni 7.78 EUR\"\n // \"sa iztegleni 400.00 EUR\"\n // \"sa plateni 0.50 EUR/0.50 EUR\" → captures 0.50 (the charged amount, ignoring fee)\n const amountMatch = message.match(/sa (?:plateni|iztegleni)\\s+([\\d.,]+)\\s+[A-Z]{3}/i);\n if (amountMatch) {\n result.amount = parseFloat(amountMatch[1].replace(',', '.'));\n }\n\n // Balance: \"Nalichni: 2583.07 EUR.\"\n const balanceMatch = message.match(/Nalichni:\\s*([\\d.,]+)\\s+[A-Z]{3}/i);\n if (balanceMatch) {\n result.balance = parseFloat(balanceMatch[1].replace(',', '.'));\n }\n\n return result;\n}\n\nmodule.exports = { parsePaymentSms };","depth":25,"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":"csvParser.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"csvParser.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"175 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/**\n * DSK Bank CSV parser — Node.js port of dskuploader.py\n *\n * DSK Bank exports use Windows-1251 (cp1251) encoding.\n * Each row maps to a Payment record with source=UPLOAD, currency=BGN.\n */\n\nconst { parse } = require('csv-parse');\nconst iconv = require('iconv-lite');\n\nconst SKIP_TYPE = 'ТРАНСФЕР СОБСТВЕНИ СМЕТКИ';\nconst CARD_REGEX = /^\\d{6}x{6}\\d{4}$/;\nconst POS_REGEX = /^\\s*ПЛАЩАНЕ\\s+НА\\s+ПОС\\s+\\d{2}\\.\\d{2}\\.\\d{4}\\s+\\d{2}:\\d{2}/;\n\nconst COL = {\n DATE: 'Дата',\n TYPE: 'Вид на трансакцията',\n REASON: 'Основание',\n DEBIT: 'Дебит BGN',\n CREDIT: 'Кредит BGN',\n PAYEE: 'Наредител/Получател',\n ACCT: 'Номер сметка на наредителя / получателя',\n};\n\nconst TAG_RULES = [\n ['reason', 'ЗАПЛАТА', 'Salary'],\n ['reason', 'ТЕГЛЕНЕ НА ATM', 'ATM'],\n ['reason', 'ПЛАЩАНЕ ПО ЗАЕМ', 'Home Credit'],\n ['reason', 'АВТ.ТАКСА ОБСЛУЖВАНЕ', 'Bills'],\n ['transactionType', 'КОМУНАЛНИ УСЛУГИ', 'Bills'],\n ['payee', 'VIVACOM', 'Subscriptions'],\n ['payee', 'Google', 'Subscriptions'],\n ['payee', 'SkyShowtime', 'Subscriptions'],\n ['payee', 'NETFLIX', 'Subscriptions'],\n ['payee', 'LUKOIL', 'Bills'],\n ['payee', 'CityGate', 'Bills'],\n ['payee', 'CBA', 'Groceries'],\n ['payee', 'FANTASTICO', 'Groceries'],\n ['payee', 'LIDL', 'Groceries'],\n];\n\nfunction parseNum(val) {\n if (val == null || val === '') return null;\n if (typeof val === 'number') return isNaN(val) ? null : val;\n const s = String(val).trim().replace(/\\xa0/g, '').replace(/ /g, '').replace(',', '.');\n const n = parseFloat(s);\n return isNaN(n) ? null : n;\n}\n\nfunction parseDate(val) {\n if (!val) return null;\n const s = String(val).trim();\n const m = s.match(/^(\\d{2})\\.(\\d{2})\\.(\\d{4})$/);\n if (m) {\n return new Date(Date.UTC(parseInt(m[3]), parseInt(m[2]) - 1, parseInt(m[1])));\n }\n return null;\n}\n\nfunction processReasonAndCard(reason) {\n if (!reason || typeof reason !== 'string') return { reason: '', card: null };\n\n const parts = reason.trim().split(' ');\n let card = null;\n let cleanReason = reason.trim();\n\n if (parts[0] && CARD_REGEX.test(parts[0])) {\n card = parts[0];\n cleanReason = parts.slice(1).join(' ').trim();\n }\n\n if (POS_REGEX.test(cleanReason)) {\n const posParts = cleanReason.split('<br/>');\n try {\n const dateTime = posParts[0].split('ПОС ')[1];\n cleanReason = `POS PAYMENT ${dateTime}`;\n } catch (_) { /* keep original */ }\n }\n\n return { reason: cleanReason.replace(/\\s+/g, ' ').trim(), card };\n}\n\nfunction generateTags(fields) {\n const tags = new Set();\n for (const [field, keyword, tagName] of TAG_RULES) {\n if ((fields[field] || '').includes(keyword)) {\n tags.add(tagName);\n }\n }\n return Array.from(tags);\n}\n\nfunction processRow(row) {\n const transactionType = (row[COL.TYPE] || '').trim();\n if (transactionType === SKIP_TYPE) return null;\n\n const { reason, card } = processReasonAndCard(row[COL.REASON]);\n const payee = (row[COL.PAYEE] || '').trim();\n const payerAccount = (row[COL.ACCT] || '').trim();\n const debitBgn = parseNum(row[COL.DEBIT]);\n const creditBgn = parseNum(row[COL.CREDIT]);\n const date = parseDate(row[COL.DATE]);\n\n const autoTags = generateTags({ reason, transactionType, payee, debitBgn, creditBgn });\n\n const amount = debitBgn ?? creditBgn ?? null;\n\n const rawMessage = [\n row[COL.DATE] && `Date: ${row[COL.DATE]}`,\n transactionType && `Type: ${transactionType}`,\n payee && `Payee: ${payee}`,\n debitBgn != null && `Debit: ${debitBgn} BGN`,\n creditBgn != null && `Credit: ${creditBgn} BGN`,\n ].filter(Boolean).join(' | ');\n\n return {\n rawMessage,\n date,\n type: null,\n card,\n recipient: payee || null,\n amount,\n currency: 'BGN',\n balance: null,\n source: 'UPLOAD',\n debitBgn,\n creditBgn,\n transactionType: transactionType || null,\n payerAccount: payerAccount || null,\n autoTags,\n };\n}\n\n/**\n * Parse a Buffer containing a DSK Bank CSV (cp1251 or UTF-8).\n * Returns { rows, skipped, errors }.\n */\nasync function parseDskCsv(buffer) {\n // Try cp1251 first (DSK Bank export encoding), fall back to UTF-8\n let text = iconv.decode(buffer, 'cp1251');\n if (!text.includes(COL.DATE)) {\n text = buffer.toString('utf-8');\n }\n\n return new Promise((resolve, reject) => {\n const rows = [];\n const errors = [];\n let skipped = 0;\n\n const parser = parse(text, {\n columns: true,\n skip_empty_lines: true,\n trim: true,\n relax_column_count: true,\n });\n\n parser.on('readable', () => {\n let record;\n while ((record = parser.read()) !== null) {\n try {\n const row = processRow(record);\n if (row === null) { skipped++; } else { rows.push(row); }\n } catch (err) {\n errors.push(err.message);\n }\n }\n });\n\n parser.on('error', reject);\n parser.on('end', () => resolve({ rows, skipped, errors }));\n });\n}\n\nmodule.exports = { parseDskCsv };","depth":25,"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":"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":"39 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"const express = require('express');\nconst cors = require('cors');\nconst morgan = require('morgan');\nconst rateLimit = require('express-rate-limit');\nconst { authentikMiddleware } = require('./auth');\nconst paymentsRouter = require('./routes/payments');\nconst uploadRouter = require('./routes/upload');\n\nconst app = express();\nconst PORT = process.env.PORT || 3001;\n\napp.use(cors());\napp.use(express.json({ limit: '16kb' }));\napp.use(morgan('combined'));\n\n// Rate-limit the public ingest endpoint before auth middleware\nconst ingestLimiter = rateLimit({\n windowMs: 60 * 1000,\n max: 200,\n standardHeaders: true,\n legacyHeaders: false,\n message: { error: 'Too many requests, slow down' },\n});\napp.use('/api/payments/ingest', ingestLimiter);\n\n// Authentik header auth (skips /api/health and /api/payments/ingest)\napp.use(authentikMiddleware);\n\napp.get('/api/health', (_req, res) => {\n res.json({ status: 'ok', timestamp: new Date().toISOString() });\n});\n\napp.use('/api/payments', paymentsRouter);\napp.use('/api/upload', uploadRouter);\n\napp.listen(PORT, '0.0.0.0', () => {\n console.log(`Finance Hub API running on port ${PORT}`);\n});","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update Todos","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Create folder structure and root config files","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend Prisma schema and migration","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend package.json and Dockerfile","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend src files (auth, parser, csvParser, index)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend routes (payments.js, upload.js)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write frontend config files","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write frontend React components","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Build and verify with docker compose","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":"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":"399 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"const express = require('express');\nconst { PrismaClient } = require('@prisma/client');\nconst { parsePaymentSms } = require('../parser');\n\nconst router = express.Router();\nconst prisma = new PrismaClient();\n\nconst NOTIFIER_URL = process.env.NOTIFIER_URL;\nconst NOTIFIER_CHANNEL = process.env.NOTIFIER_CHANNEL || 'viber';\nconst DEFAULT_PHONE = process.env.NOTIFY_DEFAULT_PHONE;\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction parseId(raw) {\n const id = parseInt(raw, 10);\n return Number.isFinite(id) ? id : null;\n}\n\nfunction formatNotifyMessage(payment) {\n const currency = payment.currency || 'EUR';\n const parts = [];\n if (payment.amount != null) parts.push(`Amount: ${payment.amount.toFixed(2)} ${currency}`);\n if (payment.recipient) parts.push(`At: ${payment.recipient}`);\n if (payment.balance != null) parts.push(`Balance: ${payment.balance.toFixed(2)} ${currency}`);\n if (payment.date) parts.push(`Date: ${new Date(payment.date).toLocaleString('en-GB')}`);\n return parts.join('\\n');\n}\n\nasync function sendNotification(payment) {\n if (!NOTIFIER_URL) {\n console.warn('[NOTIFY] NOTIFIER_URL not set — skipping notification');\n return;\n }\n\n const phone = payment.notifyPhone || DEFAULT_PHONE;\n if (!phone) {\n console.warn('[NOTIFY] No phone number for payment #' + payment.id + ' and NOTIFY_DEFAULT_PHONE not set');\n return;\n }\n\n const body = {\n phone,\n notification: NOTIFIER_CHANNEL,\n message: formatNotifyMessage(payment),\n };\n\n const res = await fetch(NOTIFIER_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`Notifier responded ${res.status}: ${text}`);\n }\n}\n\n// ── Ingest a payment (public — no auth) ──────────────────────────────────────\n//\n// Two modes:\n//\n// SMS mode (default):\n// { \"message\": \"<raw SMS text>\", \"notifyPhone\": \"...\" }\n//\n// Structured mode (Apple Wallet / manual):\n// { \"ingestMode\": \"apple_wallet\", \"amount\": 7.78, \"recipient\": \"Apple Store\",\n// \"type\": \"WALLET\", \"card\": \"••••4447\", \"date\": \"2026-02-22T10:30:00Z\" }\n//\nrouter.post('/ingest', async (req, res) => {\n try {\n const { message, notifyPhone, ingestMode } = req.body;\n\n let data;\n\n if (ingestMode === 'apple_wallet' || (!message && req.body.amount != null)) {\n // ── Structured / Apple Wallet mode ──────────────────────────────────────\n const { amount, recipient, type, card, date, balance } = req.body;\n if (amount == null || !recipient) {\n return res.status(400).json({ error: 'amount and recipient are required for structured ingest' });\n }\n\n const rawMessage = [\n `Source: ${ingestMode || 'structured'}`,\n `Amount: ${amount}`,\n recipient && `Recipient: ${recipient}`,\n type && `Type: ${type}`,\n card && `Card: ${card}`,\n ].filter(Boolean).join(' | ');\n\n data = {\n rawMessage,\n date: date ? new Date(date) : new Date(),\n type: type || 'WALLET',\n card: card || null,\n recipient,\n amount: parseFloat(amount),\n currency: 'EUR',\n balance: balance != null ? parseFloat(balance) : null,\n source: 'INGEST',\n notifyPhone: notifyPhone || null,\n };\n\n } else {\n // ── SMS mode ─────────────────────────────────────────────────────────────\n if (!message) {\n return res.status(400).json({ error: 'message is required' });\n }\n if (typeof message !== 'string' || message.length > 2000) {\n return res.status(400).json({ error: 'message must be a string under 2000 characters' });\n }\n\n const parsed = parsePaymentSms(message);\n data = {\n rawMessage: parsed.rawMessage,\n date: parsed.date,\n type: parsed.type,\n card: parsed.card,\n recipient: parsed.recipient,\n amount: parsed.amount,\n currency: 'EUR',\n balance: parsed.balance,\n source: 'INGEST',\n notifyPhone: notifyPhone || null,\n };\n }\n\n const payment = await prisma.payment.create({\n data,\n include: { tags: true },\n });\n\n res.status(201).json(payment);\n } catch (err) {\n console.error('Ingest error:', err);\n res.status(500).json({ error: 'Failed to ingest payment' });\n }\n});\n\n// ── List payments with filtering ──────────────────────────────────────────────\nrouter.get('/', async (req, res) => {\n try {\n const {\n status,\n type,\n tag,\n source,\n recipient,\n dateFrom,\n dateTo,\n search,\n sortBy = 'createdAt',\n sortDir = 'desc',\n page = 1,\n } = req.query;\n\n const limit = Math.min(parseInt(req.query.limit, 10) || 50, 200);\n\n const where = {};\n\n if (status) where.status = status;\n if (type) where.type = type;\n if (source) where.source = source;\n if (recipient) where.recipient = { contains: recipient, mode: 'insensitive' };\n if (tag) where.tags = { some: { name: tag } };\n if (search) {\n where.OR = [\n { rawMessage: { contains: search, mode: 'insensitive' } },\n { recipient: { contains: search, mode: 'insensitive' } },\n ];\n }\n if (dateFrom || dateTo) {\n where.date = {};\n if (dateFrom) where.date.gte = new Date(dateFrom);\n if (dateTo) where.date.lte = new Date(dateTo);\n }\n\n const allowedSortFields = ['date', 'amount', 'balance', 'recipient', 'type', 'source', 'createdAt', 'status'];\n const orderField = allowedSortFields.includes(sortBy) ? sortBy : 'createdAt';\n const orderDir = sortDir === 'asc' ? 'asc' : 'desc';\n\n const skip = (parseInt(page, 10) - 1) * limit;\n\n const [payments, total] = await Promise.all([\n prisma.payment.findMany({\n where,\n include: { tags: true },\n orderBy: { [orderField]: orderDir },\n skip,\n take: limit,\n }),\n prisma.payment.count({ where }),\n ]);\n\n res.json({ payments, total, page: parseInt(page, 10), limit });\n } catch (err) {\n console.error('List error:', err);\n res.status(500).json({ error: 'Failed to list payments' });\n }\n});\n\n// ── Get filter options ────────────────────────────────────────────────────────\nrouter.get('/meta/filters', async (_req, res) => {\n try {\n const [types, recipients, tags, sources] = await Promise.all([\n prisma.payment.findMany({ distinct: ['type'], select: { type: true }, where: { type: { not: null } } }),\n prisma.payment.findMany({ distinct: ['recipient'], select: { recipient: true }, where: { recipient: { not: null } } }),\n prisma.tag.findMany({ orderBy: { name: 'asc' } }),\n prisma.payment.findMany({ distinct: ['source'], select: { source: true } }),\n ]);\n\n res.json({\n types: types.map(t => t.type),\n recipients: recipients.map(r => r.recipient),\n tags,\n sources: sources.map(s => s.source),\n });\n } catch (err) {\n res.status(500).json({ error: 'Failed to get filters' });\n }\n});\n\n// ── Get all tags ──────────────────────────────────────────────────────────────\nrouter.get('/meta/tags', async (_req, res) => {\n try {\n const tags = await prisma.tag.findMany({ orderBy: { name: 'asc' } });\n res.json(tags);\n } catch (err) {\n res.status(500).json({ error: 'Failed to list tags' });\n }\n});\n\n// ── Get single payment ────────────────────────────────────────────────────────\nrouter.get('/:id', async (req, res) => {\n const id = parseId(req.params.id);\n if (id === null) return res.status(400).json({ error: 'Invalid id' });\n\n try {\n const payment = await prisma.payment.findUnique({\n where: { id },\n include: { tags: true },\n });\n if (!payment) return res.status(404).json({ error: 'Not found' });\n res.json(payment);\n } catch (err) {\n console.error('Get error:', err);\n res.status(500).json({ error: 'Failed to get payment' });\n }\n});\n\n// ── Update payment metadata (status) ─────────────────────────────────────────\nrouter.patch('/:id', async (req, res) => {\n const id = parseId(req.params.id);\n if (id === null) return res.status(400).json({ error: 'Invalid id' });\n\n try {\n const { status } = req.body;\n const data = {};\n\n if (status) {\n const validStatuses = ['UNPROCESSED', 'SENT', 'SKIPPED'];\n if (!validStatuses.includes(status)) {\n return res.status(400).json({ error: `Invalid status. Must be one of: ${validStatuses.join(', ')}` });\n }\n data.status = status;\n }\n\n if (Object.keys(data).length === 0) {\n return res.status(400).json({ error: 'No valid fields to update' });\n }\n\n const updated = await prisma.payment.update({\n where: { id },\n data,\n include: { tags: true },\n });\n res.json(updated);\n } catch (err) {\n if (err.code === 'P2025') return res.status(404).json({ error: 'Not found' });\n console.error('Update error:', err);\n res.status(500).json({ error: 'Failed to update payment' });\n }\n});\n\n// ── Delete payment ───────────────────────────────────────────────────────────\nrouter.delete('/:id', async (req, res) => {\n const id = parseId(req.params.id);\n if (id === null) return res.status(400).json({ error: 'Invalid id' });\n\n try {\n await prisma.payment.delete({ where: { id } });\n res.json({ success: true });\n } catch (err) {\n if (err.code === 'P2025') return res.status(404).json({ error: 'Not found' });\n console.error('Delete error:', err);\n res.status(500).json({ error: 'Failed to delete payment' });\n }\n});\n\n// ── Send notification (mark as SENT + call notifier service) ─────────────────\nrouter.post('/:id/send', async (req, res) => {\n const id = parseId(req.params.id);\n if (id === null) return res.status(400).json({ error: 'Invalid id' });\n\n try {\n const payment = await prisma.payment.findUnique({ where: { id } });\n if (!payment) return res.status(404).json({ error: 'Not found' });\n if (payment.status !== 'UNPROCESSED') {\n return res.status(409).json({ error: `Payment is already ${payment.status.toLowerCase()}` });\n }\n\n await sendNotification(payment);\n\n const updated = await prisma.payment.update({\n where: { id },\n data: { status: 'SENT', notifiedAt: new Date() },\n include: { tags: true },\n });\n\n res.json(updated);\n } catch (err) {\n console.error('Send error:', err);\n res.status(500).json({ error: 'Failed to send notification' });\n }\n});\n\n// ── Skip notification (mark as SKIPPED) ──────────────────────────────────────\nrouter.post('/:id/skip', async (req, res) => {\n const id = parseId(req.params.id);\n if (id === null) return res.status(400).json({ error: 'Invalid id' });\n\n try {\n const payment = await prisma.payment.findUnique({ where: { id } });\n if (!payment) return res.status(404).json({ error: 'Not found' });\n if (payment.status !== 'UNPROCESSED') {\n return res.status(409).json({ error: `Payment is already ${payment.status.toLowerCase()}` });\n }\n\n const updated = await prisma.payment.update({\n where: { id },\n data: { status: 'SKIPPED' },\n include: { tags: true },\n });\n res.json(updated);\n } catch (err) {\n console.error('Skip error:', err);\n res.status(500).json({ error: 'Failed to skip payment' });\n }\n});\n\n// ── Add tag to payment ────────────────────────────────────────────────────────\nrouter.post('/:id/tags', async (req, res) => {\n const id = parseId(req.params.id);\n if (id === null) return res.status(400).json({ error: 'Invalid id' });\n\n try {\n const { name, color } = req.body;\n if (!name) return res.status(400).json({ error: 'tag name is required' });\n\n const tag = await prisma.tag.upsert({\n where: { name },\n update: {},\n create: { name, color: color || '#6b7280' },\n });\n\n const updated = await prisma.payment.update({\n where: { id },\n data: { tags: { connect: { id: tag.id } } },\n include: { tags: true },\n });\n\n res.json(updated);\n } catch (err) {\n console.error('Tag error:', err);\n res.status(500).json({ error: 'Failed to add tag' });\n }\n});\n\n// ── Remove tag from payment ───────────────────────────────────────────────────\nrouter.delete('/:id/tags/:tagId', async (req, res) => {\n const id = parseId(req.params.id);\n const tagId = parseId(req.params.tagId);\n if (id === null || tagId === null) return res.status(400).json({ error: 'Invalid id' });\n\n try {\n const updated = await prisma.payment.update({\n where: { id },\n data: { tags: { disconnect: { id: tagId } } },\n include: { tags: true },\n });\n res.json(updated);\n } catch (err) {\n console.error('Remove tag error:', err);\n res.status(500).json({ error: 'Failed to remove tag' });\n }\n});\n\nmodule.exports = router;","depth":25,"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":"upload.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"upload.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"89 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"const express = require('express');\nconst multer = require('multer');\nconst { PrismaClient } = require('@prisma/client');\nconst { parseDskCsv } = require('../csvParser');\n\nconst router = express.Router();\nconst prisma = new PrismaClient();\n\nconst upload = multer({\n storage: multer.memoryStorage(),\n limits: { fileSize: 10 * 1024 * 1024, files: 10 },\n fileFilter: (_req, file, cb) => {\n if (file.mimetype === 'text/csv' || file.originalname.toLowerCase().endsWith('.csv')) {\n cb(null, true);\n } else {\n cb(new Error('Only CSV files are accepted'));\n }\n },\n});\n\n// POST /api/upload/csv\n// Accepts 1-10 CSV files, parses them, stores to DB with source=UPLOAD.\n// Returns { imported, skipped, errors, payments[] }\nrouter.post('/csv', upload.array('files', 10), async (req, res) => {\n if (!req.files || req.files.length === 0) {\n return res.status(400).json({ error: 'No files uploaded' });\n }\n\n const allRows = [];\n const allErrors = [];\n let totalSkipped = 0;\n\n for (const file of req.files) {\n try {\n const { rows, skipped, errors } = await parseDskCsv(file.buffer);\n allRows.push(...rows);\n totalSkipped += skipped;\n allErrors.push(...errors.map(e => `${file.originalname}: ${e}`));\n } catch (err) {\n allErrors.push(`${file.originalname}: ${err.message}`);\n }\n }\n\n if (allRows.length === 0) {\n return res.status(422).json({\n error: 'No importable rows found',\n skipped: totalSkipped,\n errors: allErrors,\n });\n }\n\n const created = [];\n\n for (const row of allRows) {\n const { autoTags, ...paymentData } = row;\n try {\n const tagConnects = [];\n for (const tagName of autoTags) {\n const tag = await prisma.tag.upsert({\n where: { name: tagName },\n update: {},\n create: { name: tagName, color: '#6b7280' },\n });\n tagConnects.push({ id: tag.id });\n }\n\n const payment = await prisma.payment.create({\n data: {\n ...paymentData,\n ...(tagConnects.length ? { tags: { connect: tagConnects } } : {}),\n },\n include: { tags: true },\n });\n created.push(payment);\n } catch (err) {\n allErrors.push(`Row insert failed: ${err.message}`);\n }\n }\n\n res.status(201).json({\n imported: created.length,\n skipped: totalSkipped,\n errors: allErrors,\n payments: created,\n });\n});\n\nmodule.exports = router;","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update Todos","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Create folder structure and root config files","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend Prisma schema and migration","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend package.json and Dockerfile","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend src files (auth, parser, csvParser, index)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend routes (payments.js, upload.js)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write frontend config files","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write frontend React components","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Build and verify with docker compose","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Now writing all frontend config files:","depth":23,"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":"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":"24 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"{\n \"name\": \"finance-hub-frontend\",\n \"version\": \"1.0.0\",\n \"type\": \"module\",\n \"scripts\": {\n \"dev\": \"vite\",\n \"build\": \"vite build\",\n \"preview\": \"vite preview\"\n },\n \"dependencies\": {\n \"lucide-react\": \"^0.460.0\",\n \"react\": \"^18.3.1\",\n \"react-dom\": \"^18.3.1\"\n },\n \"devDependencies\": {\n \"@types/react\": \"^18.3.12\",\n \"@vitejs/plugin-react\": \"^4.3.4\",\n \"autoprefixer\": \"^10.4.20\",\n \"postcss\": \"^8.4.49\",\n \"tailwindcss\": \"^3.4.15\",\n \"vite\": \"^6.0.1\"\n }\n}","depth":25,"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":"Dockerfile","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Dockerfile","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"13 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FROM node:20-alpine\n\nWORKDIR /app\n\nCOPY package.json package-lock.json* ./\nRUN npm install\n\nCOPY . .\n\nEXPOSE 5173\n\nCMD [\"npm\", \"run\", \"dev\"]","depth":25,"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":"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":"18 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"import { defineConfig } from 'vite';\nimport react from '@vitejs/plugin-react';\n\nexport default defineConfig({\n plugins: [react()],\n server: {\n host: '0.0.0.0',\n port: 5173,\n allowedHosts: ['finance-hub.lakylak.xyz'],\n proxy: {\n '/api': {\n target: 'http://backend:3001',\n changeOrigin: true,\n },\n },\n },\n});","depth":25,"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":"tailwind.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":"tailwind.config.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"12 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/** @type {import('tailwindcss').Config} */\nexport default {\n content: [\n \"./index.html\",\n \"./src/**/*.{js,ts,jsx,tsx}\",\n ],\n theme: {\n extend: {},\n },\n plugins: [],\n};","depth":25,"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":"postcss.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":"postcss.config.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"7 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"export default {\n plugins: {\n tailwindcss: {},\n autoprefixer: {},\n },\n};","depth":25,"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":"index.html","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"index.html","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"14 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Finance Hub</title>\n <link rel=\"icon\" type=\"image/svg+xml\" href=\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>💰</text></svg>\" />\n </head>\n <body class=\"bg-gray-50 min-h-screen\">\n <div id=\"root\"></div>\n <script type=\"module\" src=\"/src/main.jsx\"></script>\n </body>\n</html>","depth":25,"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":"index.css","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"index.css","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"4 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"@tailwind base;\n@tailwind components;\n@tailwind utilities;","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update Todos","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Create folder structure and root config files","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write backend Prisma schema and migration","depth":26,"on_screen":false,"role_description":"text"}]...
|
-8272345210503228720
|
6809147206053194507
|
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: finance [SSH: nas]
Explorer Section: finance [SSH: nas]
FINANCE [SSH: NAS]
auth
dsk-uploader
finance-hub
backend
frontend
scripts
.env
.env.example
.gitignore
docker-compose.yml
sms_export.json
payments-logger
.claude
auth
backend
frontend
.env
.env.example
.gitignore
API.md
docker-compose.yml
README.md
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
docker-compose.yml, Editor Group 1
.env, Editor Group 1
report(1).csv, Editor Group 1
report(2).csv, Editor Group 1
reimport_sms.sh, preview, Editor Group 1
#!/usr/bin/env bash
# Bulk re-import SMS messages from sms_export.json into finance-hub.
# Usage: bash scripts/reimport_sms.sh [--dry-run]
#
# Each record is POSTed to POST /api/payments/ingest (public, no auth needed).
# The script prints a progress line per message and a final summary.
set -euo pipefail
EXPORT_FILE="${1:-$(dirname "$0")/../sms_export.json}"
BASE_URL="${FINANCE_HUB_URL:-[URL_WITH_CREDENTIALS] @default(autoincrement())
rawMessage String @map("raw_message")
date DateTime?
type String?
card String?
recipient String?
amount Float?
currency String? @default("EUR")
balance Float?
source Source @default(INGEST)
status Status @default(UNPROCESSED)
tags Tag[]
notifiedAt DateTime? @map("notified_at")
notifyPhone String? @map("notify_phone")
debitBgn Float? @map("debit_bgn")
creditBgn Float? @map("credit_bgn")
transactionType String? @map("transaction_type")
payerAccount String? @map("payer_account")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("payments")
}
model Tag {
id Int @id @default(autoincrement())
name String @unique
color String @default("#6b7280")
payments Payment[]
@@map("tags")
}
enum Status { UNPROCESSED SENT SKIPPED }
enum Source { INGEST UPLOAD }
```
**Key decisions:**
- No `User` model — Authentik owns identity.
- `currency`: `EUR` for SMS ingest, `BGN` for CSV uploads.
- `debitBgn`, `creditBgn`, `transactionType`, `payerAccount`: nullable CSV-only columns; INGEST rows store nulls. Avoids a union query for the unified list view.
- `balance` is always null for CSV rows (DSK export does not include running balance).
- Fresh consolidated migration — no data migration from reference apps required.
---
## API Routes
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | /api/health | public | Health check |
| POST | /api/payments/ingest | public | SMS or structured ingest (source=INGEST) |
| GET | /api/payments | required | List with filters/sort/pagination (+ source filter) |
| GET | /api/payments/meta/tags | required | All tags |
| GET | /api/payments/meta/filters | required | Filter options incl. `sources` array |
| GET | /api/payments/:id | required | Single payment |
| PATCH | /api/payments/:id | required | Update status |
| DELETE | /api/payments/:id | required | Delete |
| POST | /api/payments/:id/send | required | Send notification |
| POST | /api/payments/:id/skip | required | Skip |
| POST | /api/payments/:id/tags | required | Add/upsert tag |
| DELETE | /api/payments/:id/tags/:tagId | required | Remove tag |
| POST | /api/upload/csv | required | DSK CSV file upload (source=UPLOAD) |
---
## Key Implementation Details
### auth.js (replaces entire old auth module)
```js
const PUBLIC_PATHS = new Set(['/api/health', '/api/payments/ingest']);
function authentikMiddleware(req, res, next) {
if (PUBLIC_PATHS.has(req.path)) return next();
const username = req.headers['x-authentik-username'];
if (!username) return res.status(401).json({ error: 'Unauthorized' });
req.user = {
username,
email: req.headers['x-authentik-email'] || null,
groups: (req.headers['x-authentik-groups'] || '').split(',').map(g => g.trim()).filter(Boolean),
};
next();
}
module.exports = { authentikMiddleware };
```
### csvParser.js (port of dskuploader.py)
- `iconv-lite` decodes buffer as cp1251 (DSK Bank export encoding), falls back to UTF-8
- `csv-parse` parses the decoded text with `columns: true`
- Columns: `Дата`, `Вид на трансакцията`, `Основание`, `Дебит BGN`, `Кредит BGN`, `Наредител/Получател`, `Номер сметка на наредителя / получателя`
- Card extraction: regex `/^\d{6}x{6}\d{4}$/` on first token of `Основание`
- Skips rows where `Вид на трансакцията === 'ТРАНСФЕР СОБСТВЕНИ СМЕТКИ'`
- Auto-tags via keyword rules (ЗАПЛАТА→Salary, LIDL→Groceries, NETFLIX→Subscriptions, etc.) — same logic as Python `generate_tags()`
- Returns `{ rows: PaymentData[], skipped: number, errors: string[] }`
### payments.js changes from payments-logger
1. Add `source: 'INGEST'` and `currency` to the `/ingest` create call
2. Add `source` to the `GET /` where clause filter
3. Add `sources` to `meta/filters` response
4. Currency-aware amount formatting in notification message
5. Remove all JWT/auth references (no `/auth/register`, `/auth/login`)
### upload.js (new)
- `multer` memory storage, max 10 files × 10 MB
- Calls `parseDskCsv(buffer)` per file
- Upserts tags via `prisma.tag.upsert` then connects
- Returns `{ imported, skipped, errors, payments[] }`
### Frontend changes
- **Delete**: `auth.js`, `AuthProvider.jsx`
- **main.jsx**: Remove `<AuthProvider>` wrapper
- **App.jsx**: Replace `authFetch` with plain `fetch` (Authentik session cookie travels automatically); logout → `window.location.href = '/outpost.goauthentik.io/sign_out'`; add "Payments" / "Upload CSV" tab toggle
- **FilterBar.jsx**: Add source `<select>` (All / SMS Ingest / CSV Upload); widen grid to 5 cols
- **PaymentTable.jsx**: Add `Source` column with `SMS` (indigo) / `CSV` (emerald) badge; show `${amount} ${currency}` in amount cell
- **UploadPanel.jsx** (new): Drag-and-drop zone + file list + import button + result summary with error accordion; calls `POST /api/upload/csv` with `FormData`
---
## Docker Compose
```yaml
services:
db:
image: postgres:16-alpine
environment: { POSTGRES_USER: finance, POSTGRES_PASSWORD: [PASSWORD] POSTGRES_DB: finance_hub }
volumes: [pgdata:/var/lib/postgresql/data]
healthcheck: { test: pg_isready -U finance -d finance_hub, interval: 5s }
backend:
build: ./backend
environment:
DATABASE_URL: [CONNECTION_STRING]
PORT: "3001"
NOTIFIER_URL: ${NOTIFIER_URL}
NOTIFIER_CHANNEL: ${NOTIFIER_CHANNEL:-viber}
NOTIFY_DEFAULT_PHONE: ${NOTIFY_DEFAULT_PHONE}
TZ: ${TZ:-Europe/Sofia}
ports: ["${BACKEND_PORT:-3001}:3001"]
depends_on: { db: { condition: service_healthy } }
frontend:
build: ./frontend
ports: ["${FRONTEND_PORT:-5175}:5173"]
depends_on: [backend]
volumes: { pgdata: }
```
**NPM setup:** Frontend port proxied through Authentik forward auth. Backend port exposed separately (unprotected) so the public `/api/payments/ingest` remains reachable by iOS Shortcuts / SMS gateways without login.
---
## Environment Variables (.env)
```bash
[ENV_SECRET]
NOTIFIER_URL=[URL_WITH_CREDENTIALS] @default(autoincrement())
rawMessage String @map("raw_message")
date DateTime?
type String?
card String?
recipient String?
amount Float?
currency String? @default("EUR")
balance Float?
source Source @default(INGEST)
status Status @default(UNPROCESSED)
tags Tag[]
notifiedAt DateTime? @map("notified_at")
notifyPhone String? @map("notify_phone")
debitBgn Float? @map("debit_bgn")
creditBgn Float? @map("credit_bgn")
transactionType String? @map("transaction_type")
payerAccount String? @map("payer_account")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("payments")
}
model Tag {
id Int @id @default(autoincrement())
name String @unique
color String @default("#6b7280")
payments Payment[]
@@map("tags")
}
enum Status {
UNPROCESSED
SENT
SKIPPED
}
enum Source {
INGEST
UPLOAD
}
Write
migration.sql
migration.sql
55 lines
-- CreateEnum
CREATE TYPE "Status" AS ENUM ('UNPROCESSED', 'SENT', 'SKIPPED');
CREATE TYPE "Source" AS ENUM ('INGEST', 'UPLOAD');
-- CreateTable
CREATE TABLE "payments" (
"id" SERIAL PRIMARY KEY,
"raw_message" TEXT NOT NULL,
"date" TIMESTAMP(3),
"type" TEXT,
"card" TEXT,
"recipient" TEXT,
"amount" DOUBLE PRECISION,
"currency" TEXT DEFAULT 'EUR',
"balance" DOUBLE PRECISION,
"source" "Source" NOT NULL DEFAULT 'INGEST',
"status" "Status" NOT NULL DEFAULT 'UNPROCESSED',
"notified_at" TIMESTAMP(3),
"notify_phone" TEXT,
"debit_bgn" DOUBLE PRECISION,
"credit_bgn" DOUBLE PRECISION,
"transaction_type" TEXT,
"payer_account" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- CreateTable
CREATE TABLE "tags" (
"id" SERIAL PRIMARY KEY,
"name" TEXT NOT NULL,
"color" TEXT NOT NULL DEFAULT '#6b7280'
);
-- CreateUniqueIndex
CREATE UNIQUE INDEX "tags_name_key" ON "tags"("name");
-- CreateTable (M2M join)
CREATE TABLE "_PaymentToTag" (
"A" INTEGER NOT NULL,
"B" INTEGER NOT NULL,
CONSTRAINT "_PaymentToTag_AB_pkey" PRIMARY KEY ("A", "B")
);
CREATE INDEX "_PaymentToTag_B_index" ON "_PaymentToTag"("B");
-- AddForeignKey
ALTER TABLE "_PaymentToTag"
ADD CONSTRAINT "_PaymentToTag_A_fkey"
FOREIGN KEY ("A") REFERENCES "payments"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "_PaymentToTag"
ADD CONSTRAINT "_PaymentToTag_B_fkey"
FOREIGN KEY ("B") REFERENCES "tags"("id") ON DELETE CASCADE ON UPDATE CASCADE;
Write
migration_lock.toml
migration_lock.toml
4 lines
# Please do not edit this file manually
# It should be added in your version-control system (e.g., Git)
provider = "postgresql"
Update Todos
Create folder structure and root config files
Write backend Prisma schema and migration
Write backend package.json and Dockerfile
Write backend src files (auth, parser, csvParser, index)
Write backend routes (payments.js, upload.js)
Write frontend config files
Write frontend React components
Build and verify with docker compose
Write
package.json
package.json
26 lines
{
"name": "finance-hub-backend",
"version": "1.0.0",
"main": "src/index.js",
"scripts": {
"start": "node src/index.js",
"dev": "nodemon src/index.js",
"prisma:generate": "prisma generate",
"prisma:migrate": "prisma migrate deploy"
},
"dependencies": {
"@prisma/client": "^5.22.0",
"cors": "^2.8.5",
"csv-parse": "^5.5.6",
"express": "^4.21.1",
"express-rate-limit": "^7.4.0",
"iconv-lite": "^0.6.3",
"morgan": "^1.10.0",
"multer": "^1.4.5-lts.1"
},
"devDependencies": {
"nodemon": "^3.1.7",
"prisma": "^5.22.0"
}
}
Write
Dockerfile
Dockerfile
18 lines
FROM node:20-alpine
RUN apk add --no-cache openssl
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm install
COPY prisma ./prisma
RUN npx prisma generate
COPY src ./src
EXPOSE 3001
CMD ["sh", "-c", "npx prisma migrate deploy && node src/index.js"]
Update Todos
Create folder structure and root config files
Write backend Prisma schema and migration
Write backend package.json and Dockerfile
Write backend src files (auth, parser, csvParser, index)
Write backend routes (payments.js, upload.js)
Write frontend config files
Write frontend React components
Build and verify with docker compose
Write
auth.js
auth.js
27 lines
const PUBLIC_PATHS = new Set([
'/api/health',
'/api/payments/ingest',
]);
function authentikMiddleware(req, res, next) {
if (PUBLIC_PATHS.has(req.path)) return next();
const username = req.headers['x-authentik-username'];
if (!username) {
return res.status(401).json({ error: 'Unauthorized — missing Authentik session' });
}
req.user = {
username,
email: req.headers['x-authentik-email'] || null,
groups: (req.headers['x-authentik-groups'] || '')
.split(',')
.map(g => g.trim())
.filter(Boolean),
};
next();
}
module.exports = { authentikMiddleware };
Write
parser.js
parser.js
104 lines
/**
* Parses SMS payment messages from Bulgarian banks (DSK Bank, etc.)
*
* Supported formats:
*
* POS / INTERNET / ECOM / P2P payment:
* DSK Bank. Na DD/MM/YYYY v HH:MM sa plateni AMOUNT CURRENCY s karta CARD na POS s adres: RECIPIENT. Nalichni: BALANCE CURRENCY.
*
* ATM withdrawal:
* DSK Bank. Na DD/MM/YYYY v HH:MM sa iztegleni AMOUNT CURRENCY s karta CARD ot ATM s adres: RECIPIENT. Nalichni: BALANCE CURRENCY.
*
* ATM utility payment (amount may include fee as AMOUNT/FEE):
* DSK Bank. Na DD/MM/YYYY v HH:MM sa plateni AMOUNT CURRENCY/FEE CURRENCY s karta CARD na ATM s adres:RECIPIENT. Nalichni: BALANCE CURRENCY.
*/
const LOCAL_TZ = process.env.TZ || 'Europe/Sofia';
/**
* Convert a local-timezone date/time to a UTC Date object.
* Uses Intl to resolve the actual UTC offset (DST-aware).
*/
function localToUtc(year, month, day, hour, minute) {
const naive = new Date(Date.UTC(year, month - 1, day, hour, minute, 0));
const formatter = new Intl.DateTimeFormat('en-US', {
timeZone: LOCAL_TZ,
year: 'numeric', month: '2-digit', day: '2-digit',
hour: '2-digit', minute: '2-digit', second: '2-digit',
hour12: false,
});
const parts = {};
formatter.formatToParts(naive).forEach(p => { parts[p.type] = p.value; });
const localAtNaive = new Date(Date.UTC(
parseInt(parts.year), parseInt(parts.month) - 1, parseInt(parts.day),
parseInt(parts.hour) % 24, parseInt(parts.minute), parseInt(parts.second),
));
const offsetMs = localAtNaive.getTime() - naive.getTime();
return new Date(Date.UTC(year, month - 1, day, hour, minute, 0) - offsetMs);
}
function parsePaymentSms(message) {
const result = {
rawMessage: message,
date: null,
type: null,
card: null,
recipient: null,
amount: null,
balance: null,
};
// Date and time: "Na DD/MM/YYYY v HH:MM"
const dateMatch = message.match(/Na (\d{2})\/(\d{2})\/(\d{4}) v (\d{2}):(\d{2})/i);
if (dateMatch) {
const [, day, month, year, hour, minute] = dateMatch;
result.date = localToUtc(
parseInt(year), parseInt(month), parseInt(day),
parseInt(hour), parseInt(minute),
);
}
// Card mask: "s karta 400915***4447" or "s karta 483890***7162"
const cardMatch = message.match(/s karta\s+([\d*]+)/i);
if (cardMatch) {
result.card = cardMatch[1];
}
// Transaction type: supports both prepositions
// "na POS" / "na ATM" / "na INTERNET" etc. (payment)
// "ot ATM" (withdrawal)
const typeMatch = message.match(/(?:na|ot)\s+(POS|ATM|INTERNET|ECOM|P2P)\b/i);
if (typeMatch) {
result.type = typeMatch[1].toUpperCase();
}
// Recipient address: "s adres: MERCHANT" or "s adres:MERCHANT" (no space variant)
const recipientMatch = message.match(/s adres:\s*([^.]+)\./i);
if (recipientMatch) {
result.recipient = recipientMatch[1].trim();
}
// Amount: handles both verbs and the AMOUNT/FEE suffix format
// "sa plateni 7.78 EUR"
// "sa iztegleni 400.00 EUR"
// "sa plateni 0.50 EUR/0.50 EUR" → captures 0.50 (the charged amount, ignoring fee)
const amountMatch = message.match(/sa (?:plateni|iztegleni)\s+([\d.,]+)\s+[A-Z]{3}/i);
if (amountMatch) {
result.amount = parseFloat(amountMatch[1].replace(',', '.'));
}
// Balance: "Nalichni: 2583.07 EUR."
const balanceMatch = message.match(/Nalichni:\s*([\d.,]+)\s+[A-Z]{3}/i);
if (balanceMatch) {
result.balance = parseFloat(balanceMatch[1].replace(',', '.'));
}
return result;
}
module.exports = { parsePaymentSms };
Write
csvParser.js
csvParser.js
175 lines
/**
* DSK Bank CSV parser — Node.js port of dskuploader.py
*
* DSK Bank exports use Windows-1251 (cp1251) encoding.
* Each row maps to a Payment record with source=UPLOAD, currency=BGN.
*/
const { parse } = require('csv-parse');
const iconv = require('iconv-lite');
const SKIP_TYPE = 'ТРАНСФЕР СОБСТВЕНИ СМЕТКИ';
const CARD_REGEX = /^\d{6}x{6}\d{4}$/;
const POS_REGEX = /^\s*ПЛАЩАНЕ\s+НА\s+ПОС\s+\d{2}\.\d{2}\.\d{4}\s+\d{2}:\d{2}/;
const COL = {
DATE: 'Дата',
TYPE: 'Вид на трансакцията',
REASON: 'Основание',
DEBIT: 'Дебит BGN',
CREDIT: 'Кредит BGN',
PAYEE: 'Наредител/Получател',
ACCT: 'Номер сметка на наредителя / получателя',
};
const TAG_RULES = [
['reason', 'ЗАПЛАТА', 'Salary'],
['reason', 'ТЕГЛЕНЕ НА ATM', 'ATM'],
['reason', 'ПЛАЩАНЕ ПО ЗАЕМ', 'Home Credit'],
['reason', 'АВТ.ТАКСА ОБСЛУЖВАНЕ', 'Bills'],
['transactionType', 'КОМУНАЛНИ УСЛУГИ', 'Bills'],
['payee', 'VIVACOM', 'Subscriptions'],
['payee', 'Google', 'Subscriptions'],
['payee', 'SkyShowtime', 'Subscriptions'],
['payee', 'NETFLIX', 'Subscriptions'],
['payee', 'LUKOIL', 'Bills'],
['payee', 'CityGate', 'Bills'],
['payee', 'CBA', 'Groceries'],
['payee', 'FANTASTICO', 'Groceries'],
['payee', 'LIDL', 'Groceries'],
];
function parseNum(val) {
if (val == null || val === '') return null;
if (typeof val === 'number') return isNaN(val) ? null : val;
const s = String(val).trim().replace(/\xa0/g, '').replace(/ /g, '').replace(',', '.');
const n = parseFloat(s);
return isNaN(n) ? null : n;
}
function parseDate(val) {
if (!val) return null;
const s = String(val).trim();
const m = s.match(/^(\d{2})\.(\d{2})\.(\d{4})$/);
if (m) {
return new Date(Date.UTC(parseInt(m[3]), parseInt(m[2]) - 1, parseInt(m[1])));
}
return null;
}
function processReasonAndCard(reason) {
if (!reason || typeof reason !== 'string') return { reason: '', card: null };
const parts = reason.trim().split(' ');
let card = null;
let cleanReason = reason.trim();
if (parts[0] && CARD_REGEX.test(parts[0])) {
card = parts[0];
cleanReason = parts.slice(1).join(' ').trim();
}
if (POS_REGEX.test(cleanReason)) {
const posParts = cleanReason.split('<br/>');
try {
const dateTime = posParts[0].split('ПОС ')[1];
cleanReason = `POS PAYMENT ${dateTime}`;
} catch (_) { /* keep original */ }
}
return { reason: cleanReason.replace(/\s+/g, ' ').trim(), card };
}
function generateTags(fields) {
const tags = new Set();
for (const [field, keyword, tagName] of TAG_RULES) {
if ((fields[field] || '').includes(keyword)) {
tags.add(tagName);
}
}
return Array.from(tags);
}
function processRow(row) {
const transactionType = (row[COL.TYPE] || '').trim();
if (transactionType === SKIP_TYPE) return null;
const { reason, card } = processReasonAndCard(row[COL.REASON]);
const payee = (row[COL.PAYEE] || '').trim();
const payerAccount = (row[COL.ACCT] || '').trim();
const debitBgn = parseNum(row[COL.DEBIT]);
const creditBgn = parseNum(row[COL.CREDIT]);
const date = parseDate(row[COL.DATE]);
const autoTags = generateTags({ reason, transactionType, payee, debitBgn, creditBgn });
const amount = debitBgn ?? creditBgn ?? null;
const rawMessage = [
row[COL.DATE] && `Date: ${row[COL.DATE]}`,
transactionType && `Type: ${transactionType}`,
payee && `Payee: ${payee}`,
debitBgn != null && `Debit: ${debitBgn} BGN`,
creditBgn != null && `Credit: ${creditBgn} BGN`,
].filter(Boolean).join(' | ');
return {
rawMessage,
date,
type: null,
card,
recipient: payee || null,
amount,
currency: 'BGN',
balance: null,
source: 'UPLOAD',
debitBgn,
creditBgn,
transactionType: transactionType || null,
payerAccount: payerAccount || null,
autoTags,
};
}
/**
* Parse a Buffer containing a DSK Bank CSV (cp1251 or UTF-8).
* Returns { rows, skipped, errors }.
*/
async function parseDskCsv(buffer) {
// Try cp1251 first (DSK Bank export encoding), fall back to UTF-8
let text = iconv.decode(buffer, 'cp1251');
if (!text.includes(COL.DATE)) {
text = buffer.toString('utf-8');
}
return new Promise((resolve, reject) => {
const rows = [];
const errors = [];
let skipped = 0;
const parser = parse(text, {
columns: true,
skip_...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
16650
|
744
|
20
|
2026-05-11T09:13:33.281689+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778490813281_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
Petko Kashinski
Apr 21st at 1:52:32 PM
1:52 PM
Само кажи като го направиш за да знам на какво си се спрял
Lukas Kovalik
Apr 21st at 1:53:00 PM
1:53 PM
има ли всъщност тестова среда за planhat или само прод
Petko Kashinski
Apr 21st at 1:53:35 PM
1:53 PM
Ох, много добър въпрос
Apr 21st at 1:53:35 PM
1:53
Apr 21st at 1:53:44 PM
1:53
Аз съм от ония лудите дето тестват само на прод
Apr 21st at 1:53:45 PM
1:53
хахахха
Lukas Kovalik
Apr 21st at 1:54:17 PM
1:54 PM
аз не съм чувал за такава но не съм и работил по planhat
Apr 21st at 1:54:45 PM
1:54
ок мерси, ще ти пиша, или в тикет направо когато сме готови
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 21st at 1:56:12 PM
1:56 PM
oks thx
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
Apr 22nd at 4:48:19 PM
4:48 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 4:48:25 PM
4:48
Имаш ли минутка за бърз хъдъл :?
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:49:40 PM
6:49 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: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
loading…
Channel...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":14,"bounds":{"left":0.51180553,"top":0.08111111,"width":0.025,"height":0.04},"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.50625,"top":0.14,"width":0.036111113,"height":0.075555556},"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.5138889,"top":0.19222222,"width":0.020833334,"height":0.015555556},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":14,"bounds":{"left":0.50625,"top":0.21555555,"width":0.036111113,"height":0.075555556},"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.5159722,"top":0.26777777,"width":0.016666668,"height":0.015555556},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":14,"bounds":{"left":0.50625,"top":0.2911111,"width":0.036111113,"height":0.075555556},"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.51111114,"top":0.34333333,"width":0.027083334,"height":0.015555556},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.51111114,"top":0.34333333,"width":0.0055555557,"height":0.015555556}},{"char_start":1,"char_count":7,"bounds":{"left":0.5159722,"top":0.34333333,"width":0.022222223,"height":0.015555556}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":14,"bounds":{"left":0.50625,"top":0.36666667,"width":0.036111113,"height":0.075555556},"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.51666665,"top":0.4188889,"width":0.015972223,"height":0.015555556},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.51666665,"top":0.4188889,"width":0.004166667,"height":0.015555556}},{"char_start":1,"char_count":4,"bounds":{"left":0.5208333,"top":0.4188889,"width":0.011805556,"height":0.015555556}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":14,"bounds":{"left":0.50625,"top":0.4422222,"width":0.036111113,"height":0.075555556},"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.5152778,"top":0.49444443,"width":0.018055556,"height":0.015555556},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":14,"bounds":{"left":0.50625,"top":0.5177778,"width":0.036111113,"height":0.075555556},"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.5152778,"top":0.57,"width":0.01875,"height":0.015555556},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.039583333,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.036805555,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.038194444,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.06111111,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":21,"bounds":{"left":0.68472224,"top":0.12777779,"width":0.0055555557,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.050694443,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-x-integration-app","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.09166667,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.093055554,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.046527777,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.025694445,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.038194444,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.022222223,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.072222225,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"curiosity_lab","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.057638887,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.054166667,"height":0.007777778},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":23,"bounds":{"left":0.58819443,"top":0.14666666,"width":0.034027778,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":23,"bounds":{"left":0.58819443,"top":0.17777778,"width":0.048611112,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":23,"bounds":{"left":0.58819443,"top":0.20888889,"width":0.072916664,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.20888889,"width":0.00625,"height":0.02}},{"char_start":1,"char_count":15,"bounds":{"left":0.59444445,"top":0.20888889,"width":0.06666667,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":23,"bounds":{"left":0.58819443,"top":0.24,"width":0.08055556,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"random","depth":23,"bounds":{"left":0.58819443,"top":0.2711111,"width":0.035416666,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":23,"bounds":{"left":0.58819443,"top":0.30222222,"width":0.036805555,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"sofia-office","depth":23,"bounds":{"left":0.58819443,"top":0.33333334,"width":0.05138889,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.33333334,"width":0.0048611113,"height":0.02}},{"char_start":1,"char_count":11,"bounds":{"left":0.59305555,"top":0.33333334,"width":0.045833334,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"support","depth":23,"bounds":{"left":0.58819443,"top":0.36444443,"width":0.036111113,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":23,"bounds":{"left":0.58819443,"top":0.39555556,"width":0.05138889,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":23,"bounds":{"left":0.58819443,"top":0.42666668,"width":0.094444446,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.42666668,"width":0.004166667,"height":0.02}},{"char_start":1,"char_count":20,"bounds":{"left":0.5923611,"top":0.42666668,"width":0.09861111,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":24,"bounds":{"left":0.58819443,"top":0.5,"width":0.06736111,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.5,"width":0.00625,"height":0.02}},{"char_start":1,"char_count":14,"bounds":{"left":0.59444445,"top":0.5,"width":0.065972224,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":23,"bounds":{"left":0.58819443,"top":0.5311111,"width":0.079166666,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":23,"bounds":{"left":0.58819443,"top":0.56222224,"width":0.055555556,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.56222224,"width":0.00625,"height":0.02}},{"char_start":1,"char_count":12,"bounds":{"left":0.59444445,"top":0.56222224,"width":0.048611112,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":23,"bounds":{"left":0.58819443,"top":0.5933333,"width":0.06736111,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":23,"bounds":{"left":0.58819443,"top":0.6244444,"width":0.07361111,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":23,"bounds":{"left":0.58819443,"top":0.65555555,"width":0.07847222,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"bounds":{"left":0.6666667,"top":0.65555555,"width":0.013194445,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":23,"bounds":{"left":0.6715278,"top":0.65555555,"width":0.029861111,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.6715278,"top":0.65555555,"width":0.008333334,"height":0.02}},{"char_start":1,"char_count":13,"bounds":{"left":0.6798611,"top":0.65555555,"width":0.060416665,"height":0.02}}],"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,"bounds":{"left":0.58819443,"top":0.68666667,"width":0.060416665,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Ves","depth":23,"bounds":{"left":0.58819443,"top":0.7177778,"width":0.016666668,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":23,"bounds":{"left":0.58819443,"top":0.7488889,"width":0.07847222,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"James Graham","depth":23,"bounds":{"left":0.58819443,"top":0.78,"width":0.06666667,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":23,"bounds":{"left":0.58819443,"top":0.8111111,"width":0.061805554,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"you","depth":23,"bounds":{"left":0.65555555,"top":0.8111111,"width":0.013194445,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.65555555,"top":0.8111111,"width":0.0048611113,"height":0.02}},{"char_start":1,"char_count":2,"bounds":{"left":0.66041666,"top":0.8111111,"width":0.011805556,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":23,"bounds":{"left":0.58819443,"top":0.8844444,"width":0.046527777,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":23,"bounds":{"left":0.58819443,"top":0.91555554,"width":0.025694445,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Google Calendar","depth":23,"bounds":{"left":0.58819443,"top":0.94666666,"width":0.06388889,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.94666666,"width":0.007638889,"height":0.02}},{"char_start":1,"char_count":14,"bounds":{"left":0.59583336,"top":0.94666666,"width":0.06875,"height":0.02}}],"role_description":"text"},{"role":"AXRadioButton","text":"Messages","depth":17,"bounds":{"left":0.71319443,"top":0.12777779,"width":0.06458333,"height":0.04222222},"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.7326389,"top":0.14,"width":0.039583333,"height":0.017777778},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Add canvas","depth":18,"bounds":{"left":0.7798611,"top":0.12777779,"width":0.07152778,"height":0.04222222},"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.79930556,"top":0.14,"width":0.046527777,"height":0.017777778},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":17,"bounds":{"left":0.85347223,"top":0.12777779,"width":0.04375,"height":0.04222222},"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.87291664,"top":0.14,"width":0.01875,"height":0.017777778},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.87291664,"top":0.14,"width":0.0055555557,"height":0.017777778}},{"char_start":1,"char_count":4,"bounds":{"left":0.8784722,"top":0.14,"width":0.013194445,"height":0.017777778}}],"role_description":"text"},{"role":"AXPopUpButton","text":"Add and Edit Channel Tabs","depth":17,"bounds":{"left":0.9,"top":0.12777779,"width":0.022222223,"height":0.04222222},"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":false,"role_description":"text"},{"role":"AXStaticText","text":"List","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Folder","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":22,"bounds":{"left":0.7972222,"top":0.17666666,"width":0.10486111,"height":0.031111112},"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":23,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.07569444,"height":0.0011111111},"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.8215278,"top":0.16111112,"width":0.00625,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 21st at 1:52:32 PM","depth":23,"bounds":{"left":0.82708335,"top":0.16111112,"width":0.031944446,"height":0.0011111111},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:52 PM","depth":24,"bounds":{"left":0.82708335,"top":0.16111112,"width":0.031944446,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Само кажи като го направиш за да знам на какво си се спрял","depth":24,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.2361111,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":23,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.06458333,"height":0.0011111111},"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.8111111,"top":0.16111112,"width":0.0055555557,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 21st at 1:53:00 PM","depth":23,"bounds":{"left":0.81666666,"top":0.16111112,"width":0.03125,"height":0.0011111111},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:53 PM","depth":24,"bounds":{"left":0.81666666,"top":0.16111112,"width":0.03125,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"има ли всъщност тестова среда за planhat или само прод","depth":24,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.22361112,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Petko Kashinski","depth":23,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.07569444,"height":0.0011111111},"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.8215278,"top":0.16111112,"width":0.00625,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 21st at 1:53:35 PM","depth":23,"bounds":{"left":0.82708335,"top":0.16111112,"width":0.031944446,"height":0.0011111111},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:53 PM","depth":24,"bounds":{"left":0.82708335,"top":0.16111112,"width":0.031944446,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Ох, много добър въпрос","depth":24,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.11666667,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 21st at 1:53:35 PM","depth":24,"bounds":{"left":0.72430557,"top":0.16111112,"width":0.016666668,"height":0.0011111111},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:53","depth":25,"bounds":{"left":0.72430557,"top":0.16111112,"width":0.016666668,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 21st at 1:53:44 PM","depth":24,"bounds":{"left":0.72430557,"top":0.16111112,"width":0.016666668,"height":0.0011111111},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:53","depth":25,"bounds":{"left":0.72430557,"top":0.16111112,"width":0.016666668,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Аз съм от ония лудите дето тестват само на прод","depth":24,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.21319444,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 21st at 1:53:45 PM","depth":24,"bounds":{"left":0.72430557,"top":0.16111112,"width":0.016666668,"height":0.0011111111},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:53","depth":25,"bounds":{"left":0.72430557,"top":0.16111112,"width":0.016666668,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"хахахха","depth":24,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.036805555,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":23,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.06458333,"height":0.0011111111},"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.8111111,"top":0.16111112,"width":0.0055555557,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 21st at 1:54:17 PM","depth":23,"bounds":{"left":0.81666666,"top":0.16111112,"width":0.03125,"height":0.0011111111},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:54 PM","depth":24,"bounds":{"left":0.81666666,"top":0.16111112,"width":0.03125,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"аз не съм чувал за такава но не съм и работил по planhat","depth":24,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.22291666,"height":0.035555556},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.7465278,"top":0.15222222,"width":0.0055555557,"height":0.02}},{"char_start":1,"char_count":55,"bounds":{"left":0.7465278,"top":0.15222222,"width":0.22222222,"height":0.044444446}}],"role_description":"text"},{"role":"AXLink","text":"Apr 21st at 1:54:45 PM","depth":24,"bounds":{"left":0.72430557,"top":0.21333334,"width":0.016666668,"height":0.016666668},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:54","depth":25,"bounds":{"left":0.72430557,"top":0.21333334,"width":0.016666668,"height":0.016666668},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ок мерси, ще ти пиша, или в тикет направо когато сме готови","depth":24,"bounds":{"left":0.7465278,"top":0.21,"width":0.20833333,"height":0.044444446},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.7465278,"top":0.21,"width":0.00625,"height":0.02}},{"char_start":1,"char_count":58,"bounds":{"left":0.7465278,"top":0.21,"width":0.20763889,"height":0.044444446}}],"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":25,"bounds":{"left":0.8048611,"top":0.17555556,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.82708335,"top":0.17555556,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.84930557,"top":0.17555556,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.8715278,"top":0.17555556,"width":0.022222223,"height":0.035555556},"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":25,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":25,"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":25,"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":25,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Petko Kashinski","depth":23,"bounds":{"left":0.7465278,"top":0.26555556,"width":0.07569444,"height":0.024444444},"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.8215278,"top":0.26777777,"width":0.00625,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 21st at 1:56:12 PM","depth":23,"bounds":{"left":0.82708335,"top":0.2711111,"width":0.031944446,"height":0.016666668},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:56 PM","depth":24,"bounds":{"left":0.82708335,"top":0.2711111,"width":0.031944446,"height":0.016666668},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"oks thx","depth":24,"bounds":{"left":0.7465278,"top":0.29222223,"width":0.033333335,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":25,"bounds":{"left":0.8048611,"top":0.24666667,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.82708335,"top":0.24666667,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.84930557,"top":0.24666667,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.8715278,"top":0.24666667,"width":0.022222223,"height":0.035555556},"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":25,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":25,"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":25,"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":25,"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":22,"bounds":{"left":0.7888889,"top":0.33444443,"width":0.121527776,"height":0.031111112},"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":23,"bounds":{"left":0.7465278,"top":0.37777779,"width":0.07569444,"height":0.024444444},"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.8215278,"top":0.38,"width":0.00625,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 4:48:19 PM","depth":23,"bounds":{"left":0.82708335,"top":0.38333333,"width":0.031944446,"height":0.016666668},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"4:48 PM","depth":24,"bounds":{"left":0.82708335,"top":0.38333333,"width":0.031944446,"height":0.016666668},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Лукас","depth":24,"bounds":{"left":0.7465278,"top":0.40444446,"width":0.028472222,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":25,"bounds":{"left":0.8048611,"top":0.3588889,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.82708335,"top":0.3588889,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.84930557,"top":0.3588889,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.8715278,"top":0.3588889,"width":0.022222223,"height":0.035555556},"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":25,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":25,"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":25,"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":25,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Apr 22nd at 4:48:25 PM","depth":24,"bounds":{"left":0.72430557,"top":0.44111112,"width":0.016666668,"height":0.016666668},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"4:48","depth":25,"bounds":{"left":0.72430557,"top":0.44111112,"width":0.016666668,"height":0.016666668},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Имаш ли минутка за бърз хъдъл :?","depth":24,"bounds":{"left":0.7465278,"top":0.4377778,"width":0.16666667,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":25,"bounds":{"left":0.8048611,"top":0.40333334,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.82708335,"top":0.40333334,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.84930557,"top":0.40333334,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.8715278,"top":0.40333334,"width":0.022222223,"height":0.035555556},"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":25,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":25,"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":25,"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":25,"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":23,"bounds":{"left":0.7465278,"top":0.46888888,"width":0.06458333,"height":0.024444444},"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.8111111,"top":0.47111112,"width":0.0055555557,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 6:49:40 PM","depth":23,"bounds":{"left":0.81666666,"top":0.47444445,"width":0.03125,"height":0.016666668},"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":24,"bounds":{"left":0.81666666,"top":0.47444445,"width":0.03125,"height":0.016666668},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"здрасти Петко, до сега бях в среща","depth":24,"bounds":{"left":0.7465278,"top":0.49555555,"width":0.1701389,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":25,"bounds":{"left":0.8048611,"top":0.45,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.82708335,"top":0.45,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.84930557,"top":0.45,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.8715278,"top":0.45,"width":0.022222223,"height":0.035555556},"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":25,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":25,"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":25,"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":25,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Apr 22nd at 6:49:53 PM","depth":24,"bounds":{"left":0.72430557,"top":0.5322222,"width":0.016666668,"height":0.016666668},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:49","depth":25,"bounds":{"left":0.72430557,"top":0.5322222,"width":0.016666668,"height":0.016666668},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"какво става","depth":24,"bounds":{"left":0.7465278,"top":0.5288889,"width":0.055555556,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":25,"bounds":{"left":0.8048611,"top":0.49444443,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.82708335,"top":0.49444443,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.84930557,"top":0.49444443,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.8715278,"top":0.49444443,"width":0.022222223,"height":0.035555556},"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":25,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":25,"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":25,"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":25,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Petko Kashinski","depth":23,"bounds":{"left":0.7465278,"top":0.56,"width":0.07569444,"height":0.024444444},"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.8215278,"top":0.56222224,"width":0.00625,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 6:50:38 PM","depth":23,"bounds":{"left":0.82708335,"top":0.5655556,"width":0.031944446,"height":0.016666668},"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":24,"bounds":{"left":0.82708335,"top":0.5655556,"width":0.031944446,"height":0.016666668},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Няма проблем","depth":24,"bounds":{"left":0.7465278,"top":0.58666664,"width":0.07083333,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":25,"bounds":{"left":0.8048611,"top":0.5411111,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.82708335,"top":0.5411111,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.84930557,"top":0.5411111,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.8715278,"top":0.5411111,"width":0.022222223,"height":0.035555556},"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":25,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":25,"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":25,"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":25,"on_screen":false,"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":24,"bounds":{"left":0.72430557,"top":0.62333333,"width":0.016666668,"height":0.016666668},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:50","depth":25,"bounds":{"left":0.72430557,"top":0.62333333,"width":0.016666668,"height":0.016666668},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Оправих се","depth":24,"bounds":{"left":0.7465278,"top":0.62,"width":0.057638887,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":25,"bounds":{"left":0.8048611,"top":0.58555555,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.82708335,"top":0.58555555,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.84930557,"top":0.58555555,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.8715278,"top":0.58555555,"width":0.022222223,"height":0.035555556},"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":25,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":25,"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":25,"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":25,"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":23,"bounds":{"left":0.7465278,"top":0.6511111,"width":0.06458333,"height":0.024444444},"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.8111111,"top":0.6533333,"width":0.0055555557,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 6:50:56 PM","depth":23,"bounds":{"left":0.81666666,"top":0.6566667,"width":0.03125,"height":0.016666668},"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":24,"bounds":{"left":0.81666666,"top":0.6566667,"width":0.03125,"height":0.016666668},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":25,"bounds":{"left":0.8048611,"top":0.63222224,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.82708335,"top":0.63222224,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.84930557,"top":0.63222224,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.8715278,"top":0.63222224,"width":0.022222223,"height":0.035555556},"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":25,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":25,"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":25,"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":25,"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":22,"bounds":{"left":0.8229167,"top":0.7311111,"width":0.05277778,"height":0.031111112},"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":23,"bounds":{"left":0.7465278,"top":0.77444446,"width":0.07569444,"height":0.024444444},"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.8215278,"top":0.77666664,"width":0.00625,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:11:27 PM","depth":23,"bounds":{"left":0.82708335,"top":0.78,"width":0.036805555,"height":0.016666668},"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":24,"bounds":{"left":0.82708335,"top":0.78,"width":0.036805555,"height":0.016666668},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Лукас","depth":24,"bounds":{"left":0.7465278,"top":0.8011111,"width":0.028472222,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":25,"bounds":{"left":0.8048611,"top":0.75555557,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.82708335,"top":0.75555557,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.84930557,"top":0.75555557,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.8715278,"top":0.75555557,"width":0.022222223,"height":0.035555556},"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":25,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":25,"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":25,"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":25,"on_screen":false,"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":24,"bounds":{"left":0.71944445,"top":0.8377778,"width":0.021527778,"height":0.016666668},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:11","depth":25,"bounds":{"left":0.71944445,"top":0.8377778,"width":0.021527778,"height":0.016666668},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Имаш ли 2 минутки ?","depth":24,"bounds":{"left":0.7465278,"top":0.83444446,"width":0.104166664,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.85,"top":0.83666664,"width":0.0027777778,"height":0.017777778},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"(edited)","depth":24,"bounds":{"left":0.8527778,"top":0.83666664,"width":0.029861111,"height":0.017777778},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.8527778,"top":0.83666664,"width":0.0027777778,"height":0.017777778}},{"char_start":1,"char_count":7,"bounds":{"left":0.85486114,"top":0.83666664,"width":0.027777778,"height":0.017777778}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.8826389,"top":0.83666664,"width":0.0020833334,"height":0.017777778},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":25,"bounds":{"left":0.8048611,"top":0.8,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.82708335,"top":0.8,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.84930557,"top":0.8,"width":0.022222223,"height":0.035555556},"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":25,"bounds":{"left":0.8715278,"top":0.8,"width":0.022222223,"height":0.035555556},"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":25,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":25,"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":25,"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":25,"on_screen":false,"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.71666664,"top":0.88,"width":0.26527777,"height":0.04222222},"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":false,"role_description":"text"},{"role":"AXStaticText","text":"Channel","depth":11,"on_screen":false,"role_description":"text"}]...
|
-8272280876851118708
|
-8419033296601184172
|
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
Petko Kashinski
Apr 21st at 1:52:32 PM
1:52 PM
Само кажи като го направиш за да знам на какво си се спрял
Lukas Kovalik
Apr 21st at 1:53:00 PM
1:53 PM
има ли всъщност тестова среда за planhat или само прод
Petko Kashinski
Apr 21st at 1:53:35 PM
1:53 PM
Ох, много добър въпрос
Apr 21st at 1:53:35 PM
1:53
Apr 21st at 1:53:44 PM
1:53
Аз съм от ония лудите дето тестват само на прод
Apr 21st at 1:53:45 PM
1:53
хахахха
Lukas Kovalik
Apr 21st at 1:54:17 PM
1:54 PM
аз не съм чувал за такава но не съм и работил по planhat
Apr 21st at 1:54:45 PM
1:54
ок мерси, ще ти пиша, или в тикет направо когато сме готови
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 21st at 1:56:12 PM
1:56 PM
oks thx
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
Apr 22nd at 4:48:19 PM
4:48 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 4:48:25 PM
4:48
Имаш ли минутка за бърз хъдъл :?
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:49:40 PM
6:49 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: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
loading…
Channel
SlackFileEditViewGoHistoryWindowHelpDOCKERO ₴1DEV (docker)882DEV (d)APP (-zsh)• xз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] layJY-20197-add-import-opportunity-batch-job20118-hs-opportunity-make-webhook-strategy-defaultJY-20118-make-default-hs-opportunity-sync-strategy-webhook-basedJY-20196-handle-opportunity-without-noteJY-20118-improve-opportunity-importJY-20189-handle-activity-search-on-deleted-groupsJY-20145-filter-out-converted-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-Lirroot@docker_lamp_1:/home/jiminny# ]•HomeDMsActivityFilesLater..•MoreablSupport Daily - in 2h 47 m100% C8• Mon 11 May 12:13:32ED→Describe what you are looking forJiminny ...CHSIICCTIS# general# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of_jimi...0 Direct messages& Petko Kashin...&. Stefka Stoyanova€. Vasil VasilevNikolay IvanovP. Galya DimitrovaAneliya Angelova, ...Stoyan Tanev® Ves8. Aneliya Angelovad. James GrahamLukas Kovalik y... Ol:: AppsJira CloudToastGoogle Cale...Petko Kashinski6 0Messagest Add canvas+O Filesno planhatTuesday, April 21st ~ок мерси, ще ти пиша, или в тикет направокогато сме готовиPetko Kashinski 1:56 PMoks thxWednesday, April 22nd~Petko Kashinski 4:48 PMЛукасИмаш ли минутка за бърз хъдъл :?Lukas Kovalik 6:49 PMздрасти Петко, до сега бях в срещакакво ставаPetko Kashinski 6:50 PMНяма проблемОправих сеLukas Kovalik 6:50 PMToday~Petko Kashinski 12:11 PMЛукасИмаш ли 2 минутки ? (edited)Message Petko Kashinski+...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
17080
|
764
|
11
|
2026-05-11T10:02:48.939841+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778493768939_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...
|
[{"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}]...
|
-8269438033644633083
|
-7141493146433529272
|
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...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
20741
|
900
|
26
|
2026-05-11T16:14:53.258691+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778516093258_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
Hubspot BadRequest headers debugging
More options for Hubspot BadRequest headers debugging
Screenpipe sync script failing after recent migrations
More options for Screenpipe sync script failing after recent migrations
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
Definition of incarcerated
More options for Definition of incarcerated
Lukas Pro
Get apps and extensions
Screenpipe sync script failing after recent migrations, rename chat
Screenpipe sync script failing after recent migrations
More options for Screenpipe sync script failing after recent migrations
Open sidebar
Share chat
Claude finished the response
You said: after recent updated in screenpipe (find out what are these) I am unable to run script.
You said: after recent updated in screenpipe (find out what are these) I am unable to run script.
Pasted Text, pasted, 353 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. # # Usage: # ./screenpipe_sync.sh # syncs yesterday (default) # ./screenpipe_sync.sh 2026-04-15 # sync
PASTED
after recent updated in screenpipe (find out what are these) I am unable to run script. (pasted) "lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/.screenpipe $ ~/.screenpipe/screenpipe_sync.sh 2026-05-07
[2026-05-10 11:50:45] ========================================
[2026-05-10 11:50:45] Screenpipe sync starting for: 2026-05-07
[2026-05-10 11:50:45] ========================================
[+00m00s] ▶ Preflight checks
Source DB: OK (2.2G)
NAS mount: OK /Volumes/screenpipe
Archive DB: exists ( 10G)
Data dir: OK (266 files, 292M)
[+00m05s] ▶ Counting source rows for 2026-05-07
frames: 6262
elements: 623002
ui_events: 7412
ocr_text: 1670
meetings: 2
[+00m05s] ▶ Initialising tables, indexes, FTS
creating tables ✓ 0m00s
creating indexes ✓ 0m01s
creating FTS tables ✓ 0m00s
[+00m06s] ▶ Syncing data for 2026-05-07
video_chunks ✓ 0m01s
frames (6262 rows) ⠋ Parse error near line 3: table nas.frames has 24 columns but 30 values were supplied" There were some recent changes in migrations. Here are migrations form the begining of march (approx after I installed irt first time) 20260301000000 create elements table 2026-05-06 17:27:34 True 736637f38c6e0b5547f23c870ebbc3e87ef2d8d33b22ce73f7 ... 1302167
20260301100000 fts external content 2026-05-06 17:27:34 True 44ca0e5fc3b23c19aa09d7ac3fea48de604032d5feced2615c ... 2102875
20260301200000 drop ui monitoring 2026-05-06 17:27:34 True 9ab8a4d8c0d602b491ef1a6ff36076fd7b7c12c05848201682 ... 620375
20260306000000 delete empty transcriptions 2026-05-06 17:27:34 True 5f991a21d663157a2bce5cb9f0729f02181eef817aaef5a0b8 ... 166792
20260309000000 add cloud blob id 2026-05-06 17:27:34 True e1588e32884ec5660d11bbaa995d767fb2172bb9732ad22319 ... 1450542
20260310000000 create memories 2026-05-06 17:27:34 True 4fd07e878de1dd5b8d184e7bca9ee4e6b2480bbf39e5a68ff7 ... 1135416
20260311000000 drop unused tables 2026-05-06 17:27:34 True 3d9eb9d327a61c4055b31e22082cd045e00bd7a875cbdee86b ... 547625
20260312000000 consolidate search to frames full text 2026-05-06 17:27:34 True 5a7a31a359e9e93978d46ab4759fc8cd43898c0fd325d001b7 ... 3038250
20260312000001 drop dead fts tables 2026-05-06 17:27:34 True dd8264b96b4427f40b06ac60b813b77b6d055b24dd727212c5 ... 297250
20260312000002 drop accessibility tags 2026-05-06 17:27:34 True 672b2661f7e0fc8026f2eb6cc5d24935a15db4ed4982aeb973 ... 260167
20260315000000 add frame id to memories 2026-05-06 17:27:34 True f324ec7981134e647b6497126a2b6a7467e94d271d140d0d25 ... 642250
20260316000000 add elements activity summary index 2026-05-06 17:27:34 True 5b3f99a0d58fc73d62f240319d0718963364fdee1e3a7c4866 ... 265834
20260317000000 add elements automation props 2026-05-06 17:27:34 True 4bd132d263de143c7bb0dcf2e3b8074606c58c0f79e6091d13 ... 537750
20260318000000 add elements ref frame id 2026-05-06 17:27:34 True 33282b2c342e4743f096d1e3093146e243d97f392fe4df2cb5 ... 525250
20260319000000 add sync id indexes 2026-05-06 17:27:34 True 22c7a18c918cfcc458f05fdbfe2a0b2bb65a67ae9daeec6028 ... 407083
20260320000000 add note to meetings 2026-05-06 17:27:34 True cfa45b4c98e300c40cd36942839aa20528f47ae3e7b9c86751 ... 519625
20260324000000 drop ocr text delete trigger 2026-05-06 17:27:34 True 99f445308168fc88f993c43f8e884cc4dc7e41411c86b4d3e7 ... 182209
20260326000000 add session path to pipe executions 2026-05-06 17:27:34 True 5aa266dfcd7b741a18dd3ffb6b0ca3caf2e569959074cbc3ff ... 549583
20260411000000 add elements ref frame id index 2026-05-06 17:27:34 True 378589322920e74980ea48c6b44c916cd488e47a8f6172161e ... 232083
20260415000000 frames fts external content 2026-05-06 17:27:34 True 3fdac70da2fd44bca3c3717768b57c4cbee743451b73f13de9 ... 1259250
20260423000000 add speaker id indexes 2026-05-06 17:27:34 True 80e8e0cf144ee620c81b3796196ca22b8e34f9c152ca2ffe8f ... 398709
20260429000000 add evicted at to chunks 2026-05-06 17:27:34 True 180b1d44305df17620929a69ecce60fa3ce0148905adf19ff7 ... 963833
20260502000000 add elements on screen 2026-05-06 17:27:34 True 2cf51a077a75ef32e4e1d722092053ce919bdeee151d3d91fb ... 644500
20260504120000 add document path column 2026-05-06 17:27:34 True d84f7127e1647984eeb1f89e8dffd0918525f128e4608d323f ... 593042
20260506120000 add memories sync columns 2026-05-07 06:45:22 True 800beaaa228c7fbd88fe367dc5b357adb72a3a0635da5a30f4 ... 1777417
20260501000000 add redacted columns 2026-05-08 06:25:45 True 2a4cd6714a2322ccf8f2af6084af5a05e40f460c44c1aaf874 ... 795120667
20260503000000 add frames image redacted 2026-05-08 06:25:45 True . It worked up to the point where I attemtped to remove it and install again since the retention policy doesn't clear old data and it was to big. I am basically moving data to nas and query it form there. mac is for capture only or lets say one week query using claude code. THe main consumer and interface is on nas. How to make it work so new changes won't messup my setup. Seems like I removed the whole folder it was working find runnign with @letest even I may be wrong.
Show more
10 May
Retry
Edit
Copy
Claude responded: Looking at this carefully, the error tells the whole story:
Claude responded: Looking at this carefully, the error tells the whole story:
Pinpointing schema mismatches from recent PII redaction migrations
Pinpointing schema mismatches from recent PII redaction migrations
Looking at this carefully, the error tells the whole story:
Copy to clipboard
table nas.frames has 24 columns but 30 values were supplied
Your source DB got 6 new columns from recent migrations, but the NAS archive was created earlier with the old schema.
CREATE TABLE IF NOT EXISTS
is a no-op when the table exists, so the NAS schema is frozen at whatever it was when first created. Then
INSERT ... SELECT *
does positional mapping, which blows up the moment column counts diverge.
Let me verify the recent screenpipe changes and then fix this properly.
Diagnosed schema drift, architected resilient migration strategy
Diagnosed schema drift, architected resilient migration strategy
What's happening
What's happening
The error is schema drift, not a screenpipe bug. Your source DB grew 6 columns from these migrations (most landed late April / early May with the PII work):
20260429000000 add evicted at to chunks
→
video_chunks.evicted_at
20260502000000 add elements on screen
→
elements.on_screen
20260504120000 add document path column
→
frames.document_path
20260501000000 add redacted columns
→ redacted columns on frames/ocr_text/elements (this is the big one — accompanies the new
screenpipe/pii-redactor
model)
20260503000000 add frames image redacted
→
frames.image_redacted_path
20260506120000 add memories sync columns
→ memories table
Your NAS
archive.db
was created before these landed.
CREATE TABLE IF NOT EXISTS
is a no-op on existing tables, so the NAS schema froze. Then
INSERT INTO nas.frames SELECT * FROM main.frames
does
positional
mapping → 30 source values into a 24-column NAS table → parse error.
You weren't wrong about
npx screenpipe@latest
working: removing the folder gave you a fresh local DB with the new schema, and querying still works because everything is on one schema. The mismatch only surfaces when you try to merge old + new schemas via the sync.
The fix
The fix
Two changes make this future-proof:
ensure_columns
— before each insert, diff source vs NAS columns and run
ALTER TABLE ADD COLUMN
for any new ones. SQLite handles this as a metadata-only op, so it's instant even on your 10G archive.
Explicit column lists in INSERT
— never
SELECT *
again. Build the column list dynamically from
PRAGMA table_info(<table>)
and use
INSERT INTO t (cols) SELECT cols FROM ...
. Now positional drift is structurally impossible.
Bonus: dropped columns in future migrations will also be handled gracefully — the archive keeps the column with NULLs for new rows, no errors.
Let me write the updated script.
Created a file, ran a command, read a file
Created a file, ran a command, read a file
What changed in the script
What changed in the script
Three additions, everything else preserved:
Schema helpers
(
table_columns_with_types
,
table_columns
,
table_exists
,
ensure_columns
,
build_col_list
) — pure bash + sqlite3 PRAGMA, no extra deps.
New "Reconciling NAS schema with source" step
— runs after
CREATE TABLE IF NOT EXISTS
, before indexes/FTS/inserts. For each table in
SYNC_TABLES
, it diffs source columns against NAS and
ALTER TABLE ADD COLUMN
s the missing ones. Output looks like:
Copy to clipboard
schema: frames ✓ added 4: cloud_blob_id document_path image_redacted_path text_redacted
schema: elements ✓ added 2: on_screen text_redacted
schema: video_chunks ✓ added 1: evicted_at
Explicit column lists in every INSERT
—
FRAMES_COLS=$(build_col_list frames)
builds
"id","timestamp","app_name",...
from source
PRAGMA table_info
, and the inserts use
INSERT INTO nas.t (cols) SELECT cols FROM main.t
. No more positional mapping. Column names are double-quoted so any future hyphens or reserved-word columns won't break parsing.
What to expect on the next run
What to expect on the next run
First run after dropping it in: the "Reconciling NAS schema with source" step will print the missing columns it adds to your existing 10G archive (4 on
frames
, plus a few on
elements
/
video_chunks
/
ocr_text
). Each
ALTER TABLE ADD COLUMN
is a metadata-only op in SQLite — no table rewrite, no VACUUM needed, total cost should be sub-second even on the 10G file. Then 2026-05-07 will sync normally.
After that, when Screenpipe ships the next migration, your sync just picks up the new columns automatically. No more breakage.
One thing worth knowing
One thing worth knowing
If Screenpipe ever
drops
a column in source (rare but possible — they did
drop ui monitoring
and
drop dead fts tables
earlier), the NAS will still have it, and
build_col_list
(sourced from
main
) won't reference it. New rows will have NULL for the orphaned column, old rows keep their data. That's the right archival behavior — but if you ever want to actually drop those orphan columns from NAS, that's a manual
ALTER TABLE ... DROP COLUMN
which SQLite has supported since 3.35 (your macOS Tahoe ships 3.43+, and your NAS Docker SQLite is fine).
View Screenpipe sync
Screenpipe sync
SH
Open Screenpipe sync
Open in iTerm
Copy
Give positive feedback
Give negative feedback
Retry
You said: ok but given the changes introduced is there something I may actually use
You said: ok but given the changes introduced is there something I may actually use
ok but given the changes introduced is there something I may actually use
10 May
Retry
Edit
Copy
Claude responded: Good question.
Claude responded: Good question.
Cataloging PII redactor capabilities and security categories
Cataloging PII redactor capabilities and security categories
Good question. Let me look at what these new columns actually do and which ones map to your setup, since not all of them are equal value for you.
Evaluated four practical database columns for his specific workflow needs
Evaluated four practical database columns for his specific workflow needs
Yeah, three of them are genuinely useful for your setup. The rest are cloud-sync plumbing you can ignore.
frames.document_path — most useful for you
frames.document_path
— most useful for you
Captures the path of the document/file open at frame time. This is a meaningful upgrade over relying on
app_name
+
window_name
for IDE work.
Concrete uses given your stack:
Daily activity summary
: instead of "spent 2h in PhpStorm", you can group by
document_path
and get "spent 2h in
app/Http/Controllers/ReportsController.php
" — directly tied to the JY-20458 work.
Ticket correlation
: branch names contain ticket IDs in PhpStorm window titles, but file paths are cleaner. Query
WHERE document_path LIKE '%/reports/%'...
|
[{"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":"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":"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":"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":"AXButton","text":"Definition of incarcerated","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 Definition of incarcerated","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,"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,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Screenpipe sync script failing after recent migrations, 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 sync script failing after recent migrations","depth":21,"on_screen":true,"role_description":"text"},{"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":"Open sidebar","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: after recent updated in screenpipe (find out what are these) I am unable to run script.","depth":20,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"You said: after recent updated in screenpipe (find out what are these) I am unable to run script.","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Pasted Text, pasted, 353 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. # # Usage: # ./screenpipe_sync.sh # syncs yesterday (default) # ./screenpipe_sync.sh 2026-04-15 # sync","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PASTED","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"after recent updated in screenpipe (find out what are these) I am unable to run script. (pasted) \"lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/.screenpipe $ ~/.screenpipe/screenpipe_sync.sh 2026-05-07\n[2026-05-10 11:50:45] ========================================\n[2026-05-10 11:50:45] Screenpipe sync starting for: 2026-05-07\n[2026-05-10 11:50:45] ========================================\n[+00m00s] ▶ Preflight checks\n Source DB: OK (2.2G)\n NAS mount: OK /Volumes/screenpipe\n Archive DB: exists ( 10G)\n Data dir: OK (266 files, 292M)\n[+00m05s] ▶ Counting source rows for 2026-05-07\n frames: 6262\n elements: 623002\n ui_events: 7412\n ocr_text: 1670\n meetings: 2\n[+00m05s] ▶ Initialising tables, indexes, FTS\n creating tables ✓ 0m00s\n creating indexes ✓ 0m01s\n creating FTS tables ✓ 0m00s\n[+00m06s] ▶ Syncing data for 2026-05-07\n video_chunks ✓ 0m01s\n frames (6262 rows) ⠋ Parse error near line 3: table nas.frames has 24 columns but 30 values were supplied\" There were some recent changes in migrations. Here are migrations form the begining of march (approx after I installed irt first time) 20260301000000 create elements table 2026-05-06 17:27:34 True 736637f38c6e0b5547f23c870ebbc3e87ef2d8d33b22ce73f7 ... 1302167\n20260301100000 fts external content 2026-05-06 17:27:34 True 44ca0e5fc3b23c19aa09d7ac3fea48de604032d5feced2615c ... 2102875\n20260301200000 drop ui monitoring 2026-05-06 17:27:34 True 9ab8a4d8c0d602b491ef1a6ff36076fd7b7c12c05848201682 ... 620375\n20260306000000 delete empty transcriptions 2026-05-06 17:27:34 True 5f991a21d663157a2bce5cb9f0729f02181eef817aaef5a0b8 ... 166792\n20260309000000 add cloud blob id 2026-05-06 17:27:34 True e1588e32884ec5660d11bbaa995d767fb2172bb9732ad22319 ... 1450542\n20260310000000 create memories 2026-05-06 17:27:34 True 4fd07e878de1dd5b8d184e7bca9ee4e6b2480bbf39e5a68ff7 ... 1135416\n20260311000000 drop unused tables 2026-05-06 17:27:34 True 3d9eb9d327a61c4055b31e22082cd045e00bd7a875cbdee86b ... 547625\n20260312000000 consolidate search to frames full text 2026-05-06 17:27:34 True 5a7a31a359e9e93978d46ab4759fc8cd43898c0fd325d001b7 ... 3038250\n20260312000001 drop dead fts tables 2026-05-06 17:27:34 True dd8264b96b4427f40b06ac60b813b77b6d055b24dd727212c5 ... 297250\n20260312000002 drop accessibility tags 2026-05-06 17:27:34 True 672b2661f7e0fc8026f2eb6cc5d24935a15db4ed4982aeb973 ... 260167\n20260315000000 add frame id to memories 2026-05-06 17:27:34 True f324ec7981134e647b6497126a2b6a7467e94d271d140d0d25 ... 642250\n20260316000000 add elements activity summary index 2026-05-06 17:27:34 True 5b3f99a0d58fc73d62f240319d0718963364fdee1e3a7c4866 ... 265834\n20260317000000 add elements automation props 2026-05-06 17:27:34 True 4bd132d263de143c7bb0dcf2e3b8074606c58c0f79e6091d13 ... 537750\n20260318000000 add elements ref frame id 2026-05-06 17:27:34 True 33282b2c342e4743f096d1e3093146e243d97f392fe4df2cb5 ... 525250\n20260319000000 add sync id indexes 2026-05-06 17:27:34 True 22c7a18c918cfcc458f05fdbfe2a0b2bb65a67ae9daeec6028 ... 407083\n20260320000000 add note to meetings 2026-05-06 17:27:34 True cfa45b4c98e300c40cd36942839aa20528f47ae3e7b9c86751 ... 519625\n20260324000000 drop ocr text delete trigger 2026-05-06 17:27:34 True 99f445308168fc88f993c43f8e884cc4dc7e41411c86b4d3e7 ... 182209\n20260326000000 add session path to pipe executions 2026-05-06 17:27:34 True 5aa266dfcd7b741a18dd3ffb6b0ca3caf2e569959074cbc3ff ... 549583\n20260411000000 add elements ref frame id index 2026-05-06 17:27:34 True 378589322920e74980ea48c6b44c916cd488e47a8f6172161e ... 232083\n20260415000000 frames fts external content 2026-05-06 17:27:34 True 3fdac70da2fd44bca3c3717768b57c4cbee743451b73f13de9 ... 1259250\n20260423000000 add speaker id indexes 2026-05-06 17:27:34 True 80e8e0cf144ee620c81b3796196ca22b8e34f9c152ca2ffe8f ... 398709\n20260429000000 add evicted at to chunks 2026-05-06 17:27:34 True 180b1d44305df17620929a69ecce60fa3ce0148905adf19ff7 ... 963833\n20260502000000 add elements on screen 2026-05-06 17:27:34 True 2cf51a077a75ef32e4e1d722092053ce919bdeee151d3d91fb ... 644500\n20260504120000 add document path column 2026-05-06 17:27:34 True d84f7127e1647984eeb1f89e8dffd0918525f128e4608d323f ... 593042\n20260506120000 add memories sync columns 2026-05-07 06:45:22 True 800beaaa228c7fbd88fe367dc5b357adb72a3a0635da5a30f4 ... 1777417\n20260501000000 add redacted columns 2026-05-08 06:25:45 True 2a4cd6714a2322ccf8f2af6084af5a05e40f460c44c1aaf874 ... 795120667\n20260503000000 add frames image redacted 2026-05-08 06:25:45 True . It worked up to the point where I attemtped to remove it and install again since the retention policy doesn't clear old data and it was to big. I am basically moving data to nas and query it form there. mac is for capture only or lets say one week query using claude code. THe main consumer and interface is on nas. How to make it work so new changes won't messup my setup. Seems like I removed the whole folder it was working find runnign with @letest even I may be wrong.","depth":24,"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 May","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: Looking at this carefully, the error tells the whole story:","depth":21,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Claude responded: Looking at this carefully, the error tells the whole story:","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Pinpointing schema mismatches from recent PII redaction migrations","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Pinpointing schema mismatches from recent PII redaction migrations","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Looking at this carefully, the error tells the whole story:","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":"table nas.frames has 24 columns but 30 values were supplied","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Your source DB got 6 new columns from recent migrations, but the NAS archive was created earlier with the old schema.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CREATE TABLE IF NOT EXISTS","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"is a no-op when the table exists, so the NAS schema is frozen at whatever it was when first created. Then","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"INSERT ... SELECT *","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"does positional mapping, which blows up the moment column counts diverge.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Let me verify the recent screenpipe changes and then fix this properly.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Diagnosed schema drift, architected resilient migration strategy","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Diagnosed schema drift, architected resilient migration strategy","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"What's happening","depth":24,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"What's happening","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"The error is schema drift, not a screenpipe bug. Your source DB grew 6 columns from these migrations (most landed late April / early May with the PII work):","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"20260429000000 add evicted at to chunks","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"→","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"video_chunks.evicted_at","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"20260502000000 add elements on screen","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"→","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"elements.on_screen","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"20260504120000 add document path column","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"→","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"frames.document_path","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"20260501000000 add redacted columns","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"→ redacted columns on frames/ocr_text/elements (this is the big one — accompanies the new","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"screenpipe/pii-redactor","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"model)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"20260503000000 add frames image redacted","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"→","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"frames.image_redacted_path","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"20260506120000 add memories sync columns","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"→ memories table","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Your NAS","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"archive.db","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"was created before these landed.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CREATE TABLE IF NOT EXISTS","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"is a no-op on existing tables, so the NAS schema froze. Then","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"INSERT INTO nas.frames SELECT * FROM main.frames","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"does","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"positional","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"mapping → 30 source values into a 24-column NAS table → parse error.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"You weren't wrong about","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"npx screenpipe@latest","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"working: removing the folder gave you a fresh local DB with the new schema, and querying still works because everything is on one schema. The mismatch only surfaces when you try to merge old + new schemas via the sync.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"The fix","depth":24,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"The fix","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Two changes make this future-proof:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ensure_columns","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— before each insert, diff source vs NAS columns and run","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ALTER TABLE ADD COLUMN","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"for any new ones. SQLite handles this as a metadata-only op, so it's instant even on your 10G archive.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Explicit column lists in INSERT","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— never","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SELECT *","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"again. Build the column list dynamically from","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PRAGMA table_info(<table>)","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"and use","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"INSERT INTO t (cols) SELECT cols FROM ...","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":". Now positional drift is structurally impossible.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bonus: dropped columns in future migrations will also be handled gracefully — the archive keeps the column with NULLs for new rows, no errors.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Let me write the updated script.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Created a file, ran a command, read a file","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Created a file, ran a command, read a file","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"What changed in the script","depth":24,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"What changed in the script","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Three additions, everything else preserved:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Schema helpers","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"table_columns_with_types","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"table_columns","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"table_exists","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ensure_columns","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"build_col_list","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":") — pure bash + sqlite3 PRAGMA, no extra deps.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"New \"Reconciling NAS schema with source\" step","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— runs after","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CREATE TABLE IF NOT EXISTS","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", before indexes/FTS/inserts. For each table in","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SYNC_TABLES","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", it diffs source columns against NAS and","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ALTER TABLE ADD COLUMN","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"s the missing ones. Output looks like:","depth":26,"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":"schema: frames ✓ added 4: cloud_blob_id document_path image_redacted_path text_redacted","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"schema: elements ✓ added 2: on_screen text_redacted","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"schema: video_chunks ✓ added 1: evicted_at","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Explicit column lists in every INSERT","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"—","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FRAMES_COLS=$(build_col_list frames)","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"builds","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"id\",\"timestamp\",\"app_name\",...","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"from source","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PRAGMA table_info","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", and the inserts use","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"INSERT INTO nas.t (cols) SELECT cols FROM main.t","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":". No more positional mapping. Column names are double-quoted so any future hyphens or reserved-word columns won't break parsing.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"What to expect on the next run","depth":24,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"What to expect on the next run","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"First run after dropping it in: the \"Reconciling NAS schema with source\" step will print the missing columns it adds to your existing 10G archive (4 on","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"frames","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", plus a few on","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"elements","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"video_chunks","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ocr_text","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"). Each","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ALTER TABLE ADD COLUMN","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"is a metadata-only op in SQLite — no table rewrite, no VACUUM needed, total cost should be sub-second even on the 10G file. Then 2026-05-07 will sync normally.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"After that, when Screenpipe ships the next migration, your sync just picks up the new columns automatically. No more breakage.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"One thing worth knowing","depth":24,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"One thing worth knowing","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"If Screenpipe ever","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"drops","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"a column in source (rare but possible — they did","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"drop ui monitoring","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"and","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"drop dead fts tables","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"earlier), the NAS will still have it, and","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"build_col_list","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(sourced from","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"main","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":") won't reference it. New rows will have NULL for the orphaned column, old rows keep their data. That's the right archival behavior — but if you ever want to actually drop those orphan columns from NAS, that's a manual","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ALTER TABLE ... DROP COLUMN","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"which SQLite has supported since 3.35 (your macOS Tahoe ships 3.43+, and your NAS Docker SQLite is fine).","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"View Screenpipe sync","depth":25,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Screenpipe sync","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SH","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Open Screenpipe sync","depth":26,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Open in iTerm","depth":27,"on_screen":false,"role_description":"text"},{"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":"AXButton","text":"Give positive feedback","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Give negative feedback","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"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":"AXHeading","text":"You said: ok but given the changes introduced is there something I may actually use","depth":20,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"You said: ok but given the changes introduced is there something I may actually use","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ok but given the changes introduced is there something I may actually use","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"10 May","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 question.","depth":21,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Claude responded: Good question.","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Cataloging PII redactor capabilities and security categories","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Cataloging PII redactor capabilities and security categories","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Good question. Let me look at what these new columns actually do and which ones map to your setup, since not all of them are equal value for you.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Evaluated four practical database columns for his specific workflow needs","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Evaluated four practical database columns for his specific workflow needs","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Yeah, three of them are genuinely useful for your setup. The rest are cloud-sync plumbing you can ignore.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"frames.document_path — most useful for you","depth":24,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"frames.document_path","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— most useful for you","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Captures the path of the document/file open at frame time. This is a meaningful upgrade over relying on","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app_name","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"+","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"window_name","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"for IDE work.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Concrete uses given your stack:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Daily activity summary","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":": instead of \"spent 2h in PhpStorm\", you can group by","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"document_path","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"and get \"spent 2h in","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app/Http/Controllers/ReportsController.php","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\" — directly tied to the JY-20458 work.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Ticket correlation","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":": branch names contain ticket IDs in PhpStorm window titles, but file paths are cleaner. Query","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"WHERE document_path LIKE '%/reports/%'","depth":27,"on_screen":false,"role_description":"text"}]...
|
-8268836826735974374
|
5057506620347106322
|
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
Hubspot BadRequest headers debugging
More options for Hubspot BadRequest headers debugging
Screenpipe sync script failing after recent migrations
More options for Screenpipe sync script failing after recent migrations
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
Definition of incarcerated
More options for Definition of incarcerated
Lukas Pro
Get apps and extensions
Screenpipe sync script failing after recent migrations, rename chat
Screenpipe sync script failing after recent migrations
More options for Screenpipe sync script failing after recent migrations
Open sidebar
Share chat
Claude finished the response
You said: after recent updated in screenpipe (find out what are these) I am unable to run script.
You said: after recent updated in screenpipe (find out what are these) I am unable to run script.
Pasted Text, pasted, 353 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. # # Usage: # ./screenpipe_sync.sh # syncs yesterday (default) # ./screenpipe_sync.sh 2026-04-15 # sync
PASTED
after recent updated in screenpipe (find out what are these) I am unable to run script. (pasted) "lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/.screenpipe $ ~/.screenpipe/screenpipe_sync.sh 2026-05-07
[2026-05-10 11:50:45] ========================================
[2026-05-10 11:50:45] Screenpipe sync starting for: 2026-05-07
[2026-05-10 11:50:45] ========================================
[+00m00s] ▶ Preflight checks
Source DB: OK (2.2G)
NAS mount: OK /Volumes/screenpipe
Archive DB: exists ( 10G)
Data dir: OK (266 files, 292M)
[+00m05s] ▶ Counting source rows for 2026-05-07
frames: 6262
elements: 623002
ui_events: 7412
ocr_text: 1670
meetings: 2
[+00m05s] ▶ Initialising tables, indexes, FTS
creating tables ✓ 0m00s
creating indexes ✓ 0m01s
creating FTS tables ✓ 0m00s
[+00m06s] ▶ Syncing data for 2026-05-07
video_chunks ✓ 0m01s
frames (6262 rows) ⠋ Parse error near line 3: table nas.frames has 24 columns but 30 values were supplied" There were some recent changes in migrations. Here are migrations form the begining of march (approx after I installed irt first time) 20260301000000 create elements table 2026-05-06 17:27:34 True 736637f38c6e0b5547f23c870ebbc3e87ef2d8d33b22ce73f7 ... 1302167
20260301100000 fts external content 2026-05-06 17:27:34 True 44ca0e5fc3b23c19aa09d7ac3fea48de604032d5feced2615c ... 2102875
20260301200000 drop ui monitoring 2026-05-06 17:27:34 True 9ab8a4d8c0d602b491ef1a6ff36076fd7b7c12c05848201682 ... 620375
20260306000000 delete empty transcriptions 2026-05-06 17:27:34 True 5f991a21d663157a2bce5cb9f0729f02181eef817aaef5a0b8 ... 166792
20260309000000 add cloud blob id 2026-05-06 17:27:34 True e1588e32884ec5660d11bbaa995d767fb2172bb9732ad22319 ... 1450542
20260310000000 create memories 2026-05-06 17:27:34 True 4fd07e878de1dd5b8d184e7bca9ee4e6b2480bbf39e5a68ff7 ... 1135416
20260311000000 drop unused tables 2026-05-06 17:27:34 True 3d9eb9d327a61c4055b31e22082cd045e00bd7a875cbdee86b ... 547625
20260312000000 consolidate search to frames full text 2026-05-06 17:27:34 True 5a7a31a359e9e93978d46ab4759fc8cd43898c0fd325d001b7 ... 3038250
20260312000001 drop dead fts tables 2026-05-06 17:27:34 True dd8264b96b4427f40b06ac60b813b77b6d055b24dd727212c5 ... 297250
20260312000002 drop accessibility tags 2026-05-06 17:27:34 True 672b2661f7e0fc8026f2eb6cc5d24935a15db4ed4982aeb973 ... 260167
20260315000000 add frame id to memories 2026-05-06 17:27:34 True f324ec7981134e647b6497126a2b6a7467e94d271d140d0d25 ... 642250
20260316000000 add elements activity summary index 2026-05-06 17:27:34 True 5b3f99a0d58fc73d62f240319d0718963364fdee1e3a7c4866 ... 265834
20260317000000 add elements automation props 2026-05-06 17:27:34 True 4bd132d263de143c7bb0dcf2e3b8074606c58c0f79e6091d13 ... 537750
20260318000000 add elements ref frame id 2026-05-06 17:27:34 True 33282b2c342e4743f096d1e3093146e243d97f392fe4df2cb5 ... 525250
20260319000000 add sync id indexes 2026-05-06 17:27:34 True 22c7a18c918cfcc458f05fdbfe2a0b2bb65a67ae9daeec6028 ... 407083
20260320000000 add note to meetings 2026-05-06 17:27:34 True cfa45b4c98e300c40cd36942839aa20528f47ae3e7b9c86751 ... 519625
20260324000000 drop ocr text delete trigger 2026-05-06 17:27:34 True 99f445308168fc88f993c43f8e884cc4dc7e41411c86b4d3e7 ... 182209
20260326000000 add session path to pipe executions 2026-05-06 17:27:34 True 5aa266dfcd7b741a18dd3ffb6b0ca3caf2e569959074cbc3ff ... 549583
20260411000000 add elements ref frame id index 2026-05-06 17:27:34 True 378589322920e74980ea48c6b44c916cd488e47a8f6172161e ... 232083
20260415000000 frames fts external content 2026-05-06 17:27:34 True 3fdac70da2fd44bca3c3717768b57c4cbee743451b73f13de9 ... 1259250
20260423000000 add speaker id indexes 2026-05-06 17:27:34 True 80e8e0cf144ee620c81b3796196ca22b8e34f9c152ca2ffe8f ... 398709
20260429000000 add evicted at to chunks 2026-05-06 17:27:34 True 180b1d44305df17620929a69ecce60fa3ce0148905adf19ff7 ... 963833
20260502000000 add elements on screen 2026-05-06 17:27:34 True 2cf51a077a75ef32e4e1d722092053ce919bdeee151d3d91fb ... 644500
20260504120000 add document path column 2026-05-06 17:27:34 True d84f7127e1647984eeb1f89e8dffd0918525f128e4608d323f ... 593042
20260506120000 add memories sync columns 2026-05-07 06:45:22 True 800beaaa228c7fbd88fe367dc5b357adb72a3a0635da5a30f4 ... 1777417
20260501000000 add redacted columns 2026-05-08 06:25:45 True 2a4cd6714a2322ccf8f2af6084af5a05e40f460c44c1aaf874 ... 795120667
20260503000000 add frames image redacted 2026-05-08 06:25:45 True . It worked up to the point where I attemtped to remove it and install again since the retention policy doesn't clear old data and it was to big. I am basically moving data to nas and query it form there. mac is for capture only or lets say one week query using claude code. THe main consumer and interface is on nas. How to make it work so new changes won't messup my setup. Seems like I removed the whole folder it was working find runnign with @letest even I may be wrong.
Show more
10 May
Retry
Edit
Copy
Claude responded: Looking at this carefully, the error tells the whole story:
Claude responded: Looking at this carefully, the error tells the whole story:
Pinpointing schema mismatches from recent PII redaction migrations
Pinpointing schema mismatches from recent PII redaction migrations
Looking at this carefully, the error tells the whole story:
Copy to clipboard
table nas.frames has 24 columns but 30 values were supplied
Your source DB got 6 new columns from recent migrations, but the NAS archive was created earlier with the old schema.
CREATE TABLE IF NOT EXISTS
is a no-op when the table exists, so the NAS schema is frozen at whatever it was when first created. Then
INSERT ... SELECT *
does positional mapping, which blows up the moment column counts diverge.
Let me verify the recent screenpipe changes and then fix this properly.
Diagnosed schema drift, architected resilient migration strategy
Diagnosed schema drift, architected resilient migration strategy
What's happening
What's happening
The error is schema drift, not a screenpipe bug. Your source DB grew 6 columns from these migrations (most landed late April / early May with the PII work):
20260429000000 add evicted at to chunks
→
video_chunks.evicted_at
20260502000000 add elements on screen
→
elements.on_screen
20260504120000 add document path column
→
frames.document_path
20260501000000 add redacted columns
→ redacted columns on frames/ocr_text/elements (this is the big one — accompanies the new
screenpipe/pii-redactor
model)
20260503000000 add frames image redacted
→
frames.image_redacted_path
20260506120000 add memories sync columns
→ memories table
Your NAS
archive.db
was created before these landed.
CREATE TABLE IF NOT EXISTS
is a no-op on existing tables, so the NAS schema froze. Then
INSERT INTO nas.frames SELECT * FROM main.frames
does
positional
mapping → 30 source values into a 24-column NAS table → parse error.
You weren't wrong about
npx screenpipe@latest
working: removing the folder gave you a fresh local DB with the new schema, and querying still works because everything is on one schema. The mismatch only surfaces when you try to merge old + new schemas via the sync.
The fix
The fix
Two changes make this future-proof:
ensure_columns
— before each insert, diff source vs NAS columns and run
ALTER TABLE ADD COLUMN
for any new ones. SQLite handles this as a metadata-only op, so it's instant even on your 10G archive.
Explicit column lists in INSERT
— never
SELECT *
again. Build the column list dynamically from
PRAGMA table_info(<table>)
and use
INSERT INTO t (cols) SELECT cols FROM ...
. Now positional drift is structurally impossible.
Bonus: dropped columns in future migrations will also be handled gracefully — the archive keeps the column with NULLs for new rows, no errors.
Let me write the updated script.
Created a file, ran a command, read a file
Created a file, ran a command, read a file
What changed in the script
What changed in the script
Three additions, everything else preserved:
Schema helpers
(
table_columns_with_types
,
table_columns
,
table_exists
,
ensure_columns
,
build_col_list
) — pure bash + sqlite3 PRAGMA, no extra deps.
New "Reconciling NAS schema with source" step
— runs after
CREATE TABLE IF NOT EXISTS
, before indexes/FTS/inserts. For each table in
SYNC_TABLES
, it diffs source columns against NAS and
ALTER TABLE ADD COLUMN
s the missing ones. Output looks like:
Copy to clipboard
schema: frames ✓ added 4: cloud_blob_id document_path image_redacted_path text_redacted
schema: elements ✓ added 2: on_screen text_redacted
schema: video_chunks ✓ added 1: evicted_at
Explicit column lists in every INSERT
—
FRAMES_COLS=$(build_col_list frames)
builds
"id","timestamp","app_name",...
from source
PRAGMA table_info
, and the inserts use
INSERT INTO nas.t (cols) SELECT cols FROM main.t
. No more positional mapping. Column names are double-quoted so any future hyphens or reserved-word columns won't break parsing.
What to expect on the next run
What to expect on the next run
First run after dropping it in: the "Reconciling NAS schema with source" step will print the missing columns it adds to your existing 10G archive (4 on
frames
, plus a few on
elements
/
video_chunks
/
ocr_text
). Each
ALTER TABLE ADD COLUMN
is a metadata-only op in SQLite — no table rewrite, no VACUUM needed, total cost should be sub-second even on the 10G file. Then 2026-05-07 will sync normally.
After that, when Screenpipe ships the next migration, your sync just picks up the new columns automatically. No more breakage.
One thing worth knowing
One thing worth knowing
If Screenpipe ever
drops
a column in source (rare but possible — they did
drop ui monitoring
and
drop dead fts tables
earlier), the NAS will still have it, and
build_col_list
(sourced from
main
) won't reference it. New rows will have NULL for the orphaned column, old rows keep their data. That's the right archival behavior — but if you ever want to actually drop those orphan columns from NAS, that's a manual
ALTER TABLE ... DROP COLUMN
which SQLite has supported since 3.35 (your macOS Tahoe ships 3.43+, and your NAS Docker SQLite is fine).
View Screenpipe sync
Screenpipe sync
SH
Open Screenpipe sync
Open in iTerm
Copy
Give positive feedback
Give negative feedback
Retry
You said: ok but given the changes introduced is there something I may actually use
You said: ok but given the changes introduced is there something I may actually use
ok but given the changes introduced is there something I may actually use
10 May
Retry
Edit
Copy
Claude responded: Good question.
Claude responded: Good question.
Cataloging PII redactor capabilities and security categories
Cataloging PII redactor capabilities and security categories
Good question. Let me look at what these new columns actually do and which ones map to your setup, since not all of them are equal value for you.
Evaluated four practical database columns for his specific workflow needs
Evaluated four practical database columns for his specific workflow needs
Yeah, three of them are genuinely useful for your setup. The rest are cloud-sync plumbing you can ignore.
frames.document_path — most useful for you
frames.document_path
— most useful for you
Captures the path of the document/file open at frame time. This is a meaningful upgrade over relying on
app_name
+
window_name
for IDE work.
Concrete uses given your stack:
Daily activity summary
: instead of "spent 2h in PhpStorm", you can group by
document_path
and get "spent 2h in
app/Http/Controllers/ReportsController.php
" — directly tied to the JY-20458 work.
Ticket correlation
: branch names contain ticket IDs in PhpStorm window titles, but file paths are cleaner. Query
WHERE document_path LIKE '%/reports/%'...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
11734
|
525
|
12
|
2026-05-09T06:54:50.227521+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778309690227_m1.jpg...
|
Firefox
|
Table: tags - db - Adminer — Personal
|
True
|
http://192.168.0.242:8092/?pgsql=db&username=finan
|
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
Оптичен интернет за дома - EON телевизия | Vivacom | 5G
Оптичен интернет за дома - EON телевизия | Vivacom | 5G
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - [EMAIL] - Gmail
[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - [EMAIL] - Gmail
New Tab
New Tab
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Table: tags - db - Adminer
Table: tags - db - Adminer
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
PostgreSQL
PostgreSQL
»
db
db
»
finance_hub
finance_hub
»
public
public
» Table: tags
Table: tags
Table: tags
Select data
Select data
Show structure
Show structure
Alter table
Alter table
New item
New item
Column
Type
Comment
id
integer
Auto Increment
[
nextval('tags_id_seq')
]
name
text
color
text
[
#6b7280
]
Column
id
name
color
Type
integer
Auto Increment
[
nextval('tags_id_seq')
]
text
text
[
#6b7280
]
Comment
Indexes
Indexes
PRIMARY
id
UNIQUE
name
PRIMARY
UNIQUE
id
name
Alter indexes
Alter indexes
Foreign keys
Foreign keys
Add foreign key
Add foreign key
Checks
Checks
Create check
Create check
Triggers
Triggers
Add trigger
Add trigger
Adminer 5.3.0
Adminer
Adminer
5.3.0
Language:
DB:
Schema:
SQL command
SQL command
Import
Import
Export
Export
Create table
Create table
select
select
_PaymentToTag
_PaymentToTag
select
select
_prisma_migrations
_prisma_migrations
select
select
payments
payments
select
select
tags
tags
finance
Logout
http://[IP_ADDRESS]:8092/?pgsql=db&username=finance&db=finance_hub&ns=public&table=tags...
|
[{"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":"Оптичен интернет за дома - EON телевизия | Vivacom | 5G","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Оптичен интернет за дома - EON телевизия | Vivacom | 5G","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":"[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - 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":"[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - kovaliklukas@gmail.com - Gmail","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"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":"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":"Table: tags - db - Adminer","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Table: tags - db - Adminer","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,"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":"AXLink","text":"PostgreSQL","depth":8,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"PostgreSQL","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":"AXLink","text":"db","depth":8,"on_screen":true,"help_text":"Alt+Shift+1","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"db","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":"AXLink","text":"finance_hub","depth":8,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"finance_hub","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":"AXLink","text":"public","depth":8,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"public","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"» Table: tags","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Table: tags","depth":7,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Table: tags","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Select data","depth":8,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select data","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Show structure","depth":8,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show structure","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Alter table","depth":8,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Alter table","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New item","depth":8,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New item","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Column","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Type","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Comment","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"id","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"integer","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Auto Increment","depth":10,"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":"nextval('tags_id_seq')","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":"name","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"color","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","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":"#6b7280","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":"Column","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"id","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"name","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"color","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":"integer","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Auto Increment","depth":10,"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":"nextval('tags_id_seq')","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":"text","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","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":"#6b7280","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":"Comment","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Indexes","depth":7,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Indexes","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PRIMARY","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"id","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNIQUE","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"name","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PRIMARY","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNIQUE","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"id","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"name","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Alter indexes","depth":8,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Alter indexes","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Foreign keys","depth":7,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Foreign keys","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add foreign key","depth":8,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add foreign key","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Checks","depth":7,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Checks","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Create check","depth":8,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create check","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Triggers","depth":7,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Triggers","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add trigger","depth":8,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add trigger","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Adminer 5.3.0","depth":8,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"Adminer","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Adminer","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.3.0","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Language:","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DB:","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Schema:","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SQL command","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SQL command","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Import","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Import","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Export","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Export","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Create table","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create table","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"select","depth":10,"on_screen":true,"help_text":"Select data","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"select","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"_PaymentToTag","depth":10,"on_screen":true,"help_text":"Show structure","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"_PaymentToTag","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"select","depth":10,"on_screen":true,"help_text":"Select data","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"select","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"_prisma_migrations","depth":10,"on_screen":true,"help_text":"Show structure","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"_prisma_migrations","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"select","depth":10,"on_screen":true,"help_text":"Select data","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"select","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"payments","depth":10,"on_screen":true,"help_text":"Show structure","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"payments","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"select","depth":10,"on_screen":true,"help_text":"Select data","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"select","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"tags","depth":10,"on_screen":true,"help_text":"Show structure","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":"AXStaticText","text":"finance","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Logout","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"http://192.168.0.242:8092/?pgsql=db&username=finance&db=finance_hub&ns=public&table=tags","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8267686188830827749
|
465155762715710751
|
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
Оптичен интернет за дома - EON телевизия | Vivacom | 5G
Оптичен интернет за дома - EON телевизия | Vivacom | 5G
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - [EMAIL] - Gmail
[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - [EMAIL] - Gmail
New Tab
New Tab
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Table: tags - db - Adminer
Table: tags - db - Adminer
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
PostgreSQL
PostgreSQL
»
db
db
»
finance_hub
finance_hub
»
public
public
» Table: tags
Table: tags
Table: tags
Select data
Select data
Show structure
Show structure
Alter table
Alter table
New item
New item
Column
Type
Comment
id
integer
Auto Increment
[
nextval('tags_id_seq')
]
name
text
color
text
[
#6b7280
]
Column
id
name
color
Type
integer
Auto Increment
[
nextval('tags_id_seq')
]
text
text
[
#6b7280
]
Comment
Indexes
Indexes
PRIMARY
id
UNIQUE
name
PRIMARY
UNIQUE
id
name
Alter indexes
Alter indexes
Foreign keys
Foreign keys
Add foreign key
Add foreign key
Checks
Checks
Create check
Create check
Triggers
Triggers
Add trigger
Add trigger
Adminer 5.3.0
Adminer
Adminer
5.3.0
Language:
DB:
Schema:
SQL command
SQL command
Import
Import
Export
Export
Create table
Create table
select
select
_PaymentToTag
_PaymentToTag
select
select
_prisma_migrations
_prisma_migrations
select
select
payments
payments
select
select
tags
tags
finance
Logout
http://[IP_ADDRESS]:8092/?pgsql=db&username=finance&db=finance_hub&ns=public&table=tags...
|
11732
|
NULL
|
NULL
|
NULL
|
|
11735
|
526
|
13
|
2026-05-09T06:54:50.227530+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778309690227_m2.jpg...
|
Firefox
|
Table: tags - db - Adminer — Personal
|
True
|
http://192.168.0.242:8092/?pgsql=db&username=finan
|
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
Оптичен интернет за дома - EON телевизия | Vivacom | 5G
Оптичен интернет за дома - EON телевизия | Vivacom | 5G
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - [EMAIL] - Gmail
[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - [EMAIL] - Gmail
New Tab
New Tab
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Table: tags - db - Adminer
Table: tags - db - Adminer
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
PostgreSQL
PostgreSQL
»
db
db
»
finance_hub
finance_hub
»
public
public
» Table: tags
Table: tags
Table: tags
Select data
Select data
Show structure
Show structure
Alter table
Alter table
New item
New item
Column
Type
Comment
id
integer
Auto Increment
[
nextval('tags_id_seq')
]
name
text
color
text
[
#6b7280
]
Column
id
name
color
Type
integer
Auto Increment
[
nextval('tags_id_seq')
]
text
text
[
#6b7280
]
Comment
Indexes
Indexes
PRIMARY
id
UNIQUE
name
PRIMARY
UNIQUE
id
name
Alter indexes
Alter indexes
Foreign keys
Foreign keys
Add foreign key
Add foreign key
Checks
Checks
Create check
Create check
Triggers
Triggers
Add trigger
Add trigger
Adminer 5.3.0
Adminer
Adminer
5.3.0
Language:
DB:
Schema:
SQL command
SQL command
Import
Import
Export
Export
Create table
Create table
select
select
_PaymentToTag
_PaymentToTag
select
select
_prisma_migrations
_prisma_migrations
select
select
payments
payments
select
select
tags
tags
finance
Logout
http://[IP_ADDRESS]:8092/?pgsql=db&username=finance&db=finance_hub&ns=public&table=tags...
|
[{"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":"Оптичен интернет за дома - EON телевизия | Vivacom | 5G","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":"Оптичен интернет за дома - EON телевизия | Vivacom | 5G","depth":5,"bounds":{"left":0.013297873,"top":0.32482043,"width":0.105884306,"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.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":"AFFiNE - All In One KnowledgeOS","depth":5,"bounds":{"left":0.013297873,"top":0.3575419,"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.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":"All docs · AFFiNE","depth":5,"bounds":{"left":0.013297873,"top":0.39026338,"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.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":"Payments Logger","depth":5,"bounds":{"left":0.013297873,"top":0.42298484,"width":0.030086435,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - kovaliklukas@gmail.com - Gmail","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":"[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - kovaliklukas@gmail.com - Gmail","depth":5,"bounds":{"left":0.013297873,"top":0.4557063,"width":0.22639628,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","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":"New Tab","depth":5,"bounds":{"left":0.013297873,"top":0.4884278,"width":0.014960106,"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.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":"Location Logger","depth":5,"bounds":{"left":0.013297873,"top":0.5211492,"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.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":false},{"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":"AXRadioButton","text":"Finance Hub","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":"Finance Hub","depth":5,"bounds":{"left":0.013297873,"top":0.5865922,"width":0.021609042,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Table: tags - db - Adminer","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":true},{"role":"AXStaticText","text":"Table: tags - db - Adminer","depth":5,"bounds":{"left":0.013297873,"top":0.61931366,"width":0.045545213,"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.61532325,"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.0028257978,"top":0.6424581,"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":"AXLink","text":"PostgreSQL","depth":8,"bounds":{"left":0.2130984,"top":0.055067837,"width":0.027593086,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"PostgreSQL","depth":9,"bounds":{"left":0.2130984,"top":0.055067837,"width":0.027593086,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"»","depth":8,"bounds":{"left":0.24069148,"top":0.055067837,"width":0.006482713,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"db","depth":8,"bounds":{"left":0.2471742,"top":0.055067837,"width":0.005984043,"height":0.014365523},"on_screen":true,"help_text":"Alt+Shift+1","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"db","depth":9,"bounds":{"left":0.2471742,"top":0.055067837,"width":0.005984043,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"»","depth":8,"bounds":{"left":0.25315824,"top":0.055067837,"width":0.0063164895,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"finance_hub","depth":8,"bounds":{"left":0.25947472,"top":0.055067837,"width":0.029421542,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"finance_hub","depth":9,"bounds":{"left":0.25947472,"top":0.055067837,"width":0.029421542,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"»","depth":8,"bounds":{"left":0.28889626,"top":0.055067837,"width":0.006482713,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"public","depth":8,"bounds":{"left":0.29537898,"top":0.055067837,"width":0.01412899,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"public","depth":9,"bounds":{"left":0.29537898,"top":0.055067837,"width":0.01412899,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"» Table: tags","depth":8,"bounds":{"left":0.30950797,"top":0.055067837,"width":0.032912236,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Table: tags","depth":7,"bounds":{"left":0.20827793,"top":0.0830008,"width":0.78507316,"height":0.04988029},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Table: tags","depth":8,"bounds":{"left":0.21542554,"top":0.096568234,"width":0.039727394,"height":0.021548284},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Select data","depth":8,"bounds":{"left":0.21426196,"top":0.14884278,"width":0.026928192,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select data","depth":9,"bounds":{"left":0.21426196,"top":0.14884278,"width":0.026928192,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Show structure","depth":8,"bounds":{"left":0.24950133,"top":0.14884278,"width":0.041223403,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show structure","depth":9,"bounds":{"left":0.24950133,"top":0.14884278,"width":0.041223403,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Alter table","depth":8,"bounds":{"left":0.2990359,"top":0.14884278,"width":0.024933511,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Alter table","depth":9,"bounds":{"left":0.2990359,"top":0.14884278,"width":0.024933511,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New item","depth":8,"bounds":{"left":0.3324468,"top":0.14884278,"width":0.022606382,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New item","depth":9,"bounds":{"left":0.3324468,"top":0.14884278,"width":0.022606382,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Column","depth":11,"bounds":{"left":0.21675532,"top":0.1763767,"width":0.018284574,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Type","depth":11,"bounds":{"left":0.23869681,"top":0.1763767,"width":0.010139627,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Comment","depth":11,"bounds":{"left":0.35272607,"top":0.1763767,"width":0.020944148,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"id","depth":10,"bounds":{"left":0.2159242,"top":0.19393456,"width":0.004488032,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"integer","depth":11,"bounds":{"left":0.23869681,"top":0.19393456,"width":0.015292553,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Auto Increment","depth":10,"bounds":{"left":0.2554854,"top":0.19393456,"width":0.033909574,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[","depth":11,"bounds":{"left":0.29089096,"top":0.19393456,"width":0.0019946808,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"nextval('tags_id_seq')","depth":11,"bounds":{"left":0.29288563,"top":0.19393456,"width":0.05501995,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"]","depth":11,"bounds":{"left":0.34790558,"top":0.19393456,"width":0.0018284575,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"name","depth":10,"bounds":{"left":0.2159242,"top":0.21189146,"width":0.013297873,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.23869681,"top":0.21189146,"width":0.008643617,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"color","depth":10,"bounds":{"left":0.2159242,"top":0.22984837,"width":0.011968086,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.23869681,"top":0.22984837,"width":0.008643617,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[","depth":11,"bounds":{"left":0.24883644,"top":0.22984837,"width":0.0018284575,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"#6b7280","depth":11,"bounds":{"left":0.2506649,"top":0.22984837,"width":0.022107713,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"]","depth":11,"bounds":{"left":0.2727726,"top":0.22984837,"width":0.0019946808,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Column","depth":10,"bounds":{"left":0.21675532,"top":0.1763767,"width":0.018284574,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"id","depth":10,"bounds":{"left":0.2159242,"top":0.19393456,"width":0.004488032,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"name","depth":10,"bounds":{"left":0.2159242,"top":0.21189146,"width":0.013297873,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"color","depth":10,"bounds":{"left":0.2159242,"top":0.22984837,"width":0.011968086,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Type","depth":10,"bounds":{"left":0.23869681,"top":0.1763767,"width":0.010139627,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"integer","depth":11,"bounds":{"left":0.23869681,"top":0.19393456,"width":0.015292553,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Auto Increment","depth":10,"bounds":{"left":0.2554854,"top":0.19393456,"width":0.033909574,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[","depth":11,"bounds":{"left":0.29089096,"top":0.19393456,"width":0.0019946808,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"nextval('tags_id_seq')","depth":11,"bounds":{"left":0.29288563,"top":0.19393456,"width":0.05501995,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"]","depth":11,"bounds":{"left":0.34790558,"top":0.19393456,"width":0.0018284575,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.23869681,"top":0.21189146,"width":0.008643617,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.23869681,"top":0.22984837,"width":0.008643617,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[","depth":11,"bounds":{"left":0.24883644,"top":0.22984837,"width":0.0018284575,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"#6b7280","depth":11,"bounds":{"left":0.2506649,"top":0.22984837,"width":0.022107713,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"]","depth":11,"bounds":{"left":0.2727726,"top":0.22984837,"width":0.0019946808,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Comment","depth":10,"bounds":{"left":0.35272607,"top":0.1763767,"width":0.020944148,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Indexes","depth":7,"bounds":{"left":0.21426196,"top":0.2605746,"width":0.7790891,"height":0.018754989},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Indexes","depth":8,"bounds":{"left":0.21426196,"top":0.26097366,"width":0.024601065,"height":0.018355945},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PRIMARY","depth":10,"bounds":{"left":0.2159242,"top":0.292498,"width":0.022772606,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"id","depth":10,"bounds":{"left":0.24168883,"top":0.292498,"width":0.0038231383,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNIQUE","depth":10,"bounds":{"left":0.2159242,"top":0.3104549,"width":0.019614361,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"name","depth":10,"bounds":{"left":0.24168883,"top":0.3104549,"width":0.011968086,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PRIMARY","depth":10,"bounds":{"left":0.2159242,"top":0.292498,"width":0.022772606,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNIQUE","depth":10,"bounds":{"left":0.2159242,"top":0.3104549,"width":0.019614361,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"id","depth":10,"bounds":{"left":0.24168883,"top":0.292498,"width":0.0038231383,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"name","depth":10,"bounds":{"left":0.24168883,"top":0.3104549,"width":0.011968086,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Alter indexes","depth":8,"bounds":{"left":0.21426196,"top":0.33559456,"width":0.03125,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Alter indexes","depth":9,"bounds":{"left":0.21426196,"top":0.33559456,"width":0.03125,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Foreign keys","depth":7,"bounds":{"left":0.21426196,"top":0.36472467,"width":0.7790891,"height":0.018754989},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Foreign keys","depth":8,"bounds":{"left":0.21426196,"top":0.3651237,"width":0.03956117,"height":0.018355945},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add foreign key","depth":8,"bounds":{"left":0.21426196,"top":0.3926576,"width":0.037898935,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add foreign key","depth":9,"bounds":{"left":0.21426196,"top":0.3926576,"width":0.037898935,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Checks","depth":7,"bounds":{"left":0.21426196,"top":0.4217877,"width":0.7790891,"height":0.018754989},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Checks","depth":8,"bounds":{"left":0.21426196,"top":0.42218676,"width":0.022107713,"height":0.018355945},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Create check","depth":8,"bounds":{"left":0.21426196,"top":0.44972068,"width":0.03125,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create check","depth":9,"bounds":{"left":0.21426196,"top":0.44972068,"width":0.03125,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Triggers","depth":7,"bounds":{"left":0.21426196,"top":0.4792498,"width":0.7790891,"height":0.018355945},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Triggers","depth":8,"bounds":{"left":0.21426196,"top":0.4792498,"width":0.024933511,"height":0.018355945},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add trigger","depth":8,"bounds":{"left":0.21426196,"top":0.5067837,"width":0.026928192,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add trigger","depth":9,"bounds":{"left":0.21426196,"top":0.5067837,"width":0.026928192,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Adminer 5.3.0","depth":8,"bounds":{"left":0.113696806,"top":0.0830008,"width":0.0909242,"height":0.04988029},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"Adminer","depth":9,"bounds":{"left":0.11851729,"top":0.096568234,"width":0.038231384,"height":0.021548284},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Adminer","depth":10,"bounds":{"left":0.12649602,"top":0.096568234,"width":0.03025266,"height":0.021548284},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.3.0","depth":9,"bounds":{"left":0.15924202,"top":0.10335196,"width":0.011635638,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Language:","depth":11,"bounds":{"left":0.11851729,"top":0.056664005,"width":0.027094414,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DB:","depth":11,"bounds":{"left":0.11851729,"top":0.1424581,"width":0.010804521,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Schema:","depth":11,"bounds":{"left":0.11851729,"top":0.16001596,"width":0.022938829,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SQL command","depth":9,"bounds":{"left":0.11851729,"top":0.1963288,"width":0.034906916,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SQL command","depth":10,"bounds":{"left":0.11851729,"top":0.1963288,"width":0.034906916,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Import","depth":9,"bounds":{"left":0.16173537,"top":0.1963288,"width":0.01662234,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Import","depth":10,"bounds":{"left":0.16173537,"top":0.1963288,"width":0.01662234,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Export","depth":9,"bounds":{"left":0.11851729,"top":0.21069433,"width":0.015625,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Export","depth":10,"bounds":{"left":0.11851729,"top":0.21069433,"width":0.015625,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Create table","depth":9,"bounds":{"left":0.14245346,"top":0.21069433,"width":0.029421542,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create table","depth":10,"bounds":{"left":0.14245346,"top":0.21069433,"width":0.029421542,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"select","depth":10,"bounds":{"left":0.11851729,"top":0.2442139,"width":0.013796543,"height":0.014365523},"on_screen":true,"help_text":"Select data","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"select","depth":11,"bounds":{"left":0.11851729,"top":0.2442139,"width":0.013796543,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"_PaymentToTag","depth":10,"bounds":{"left":0.1341423,"top":0.2442139,"width":0.037400264,"height":0.014365523},"on_screen":true,"help_text":"Show structure","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"_PaymentToTag","depth":11,"bounds":{"left":0.1341423,"top":0.2442139,"width":0.037400264,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"select","depth":10,"bounds":{"left":0.11851729,"top":0.2585794,"width":0.013796543,"height":0.014365523},"on_screen":true,"help_text":"Select data","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"select","depth":11,"bounds":{"left":0.11851729,"top":0.2585794,"width":0.013796543,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"_prisma_migrations","depth":10,"bounds":{"left":0.1341423,"top":0.2585794,"width":0.047706116,"height":0.014365523},"on_screen":true,"help_text":"Show structure","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"_prisma_migrations","depth":11,"bounds":{"left":0.1341423,"top":0.2585794,"width":0.047706116,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"select","depth":10,"bounds":{"left":0.11851729,"top":0.27294493,"width":0.013796543,"height":0.014365523},"on_screen":true,"help_text":"Select data","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"select","depth":11,"bounds":{"left":0.11851729,"top":0.27294493,"width":0.013796543,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"payments","depth":10,"bounds":{"left":0.1341423,"top":0.27294493,"width":0.0234375,"height":0.014365523},"on_screen":true,"help_text":"Show structure","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"payments","depth":11,"bounds":{"left":0.1341423,"top":0.27294493,"width":0.0234375,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"select","depth":10,"bounds":{"left":0.11851729,"top":0.28731045,"width":0.013796543,"height":0.014365523},"on_screen":true,"help_text":"Select data","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"select","depth":11,"bounds":{"left":0.11851729,"top":0.28731045,"width":0.013796543,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"tags","depth":10,"bounds":{"left":0.1341423,"top":0.28731045,"width":0.011469414,"height":0.014365523},"on_screen":true,"help_text":"Show structure","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"tags","depth":11,"bounds":{"left":0.1341423,"top":0.28731045,"width":0.011469414,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"finance","depth":9,"bounds":{"left":0.95611703,"top":0.057861134,"width":0.018949468,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Logout","depth":9,"bounds":{"left":0.9750665,"top":0.057462092,"width":0.018284574,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"http://192.168.0.242:8092/?pgsql=db&username=finance&db=finance_hub&ns=public&table=tags","depth":5,"bounds":{"left":0.11502659,"top":0.9876297,"width":0.17170878,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8267686188830827749
|
465155762715710751
|
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
Оптичен интернет за дома - EON телевизия | Vivacom | 5G
Оптичен интернет за дома - EON телевизия | Vivacom | 5G
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - [EMAIL] - Gmail
[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - [EMAIL] - Gmail
New Tab
New Tab
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Table: tags - db - Adminer
Table: tags - db - Adminer
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
PostgreSQL
PostgreSQL
»
db
db
»
finance_hub
finance_hub
»
public
public
» Table: tags
Table: tags
Table: tags
Select data
Select data
Show structure
Show structure
Alter table
Alter table
New item
New item
Column
Type
Comment
id
integer
Auto Increment
[
nextval('tags_id_seq')
]
name
text
color
text
[
#6b7280
]
Column
id
name
color
Type
integer
Auto Increment
[
nextval('tags_id_seq')
]
text
text
[
#6b7280
]
Comment
Indexes
Indexes
PRIMARY
id
UNIQUE
name
PRIMARY
UNIQUE
id
name
Alter indexes
Alter indexes
Foreign keys
Foreign keys
Add foreign key
Add foreign key
Checks
Checks
Create check
Create check
Triggers
Triggers
Add trigger
Add trigger
Adminer 5.3.0
Adminer
Adminer
5.3.0
Language:
DB:
Schema:
SQL command
SQL command
Import
Import
Export
Export
Create table
Create table
select
select
_PaymentToTag
_PaymentToTag
select
select
_prisma_migrations
_prisma_migrations
select
select
payments
payments
select
select
tags
tags
finance
Logout
http://[IP_ADDRESS]:8092/?pgsql=db&username=finance&db=finance_hub&ns=public&table=tags...
|
11733
|
NULL
|
NULL
|
NULL
|
|
17393
|
770
|
28
|
2026-05-11T10:21:29.846155+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778494889846_m1.jpg...
|
PhpStorm
|
faVsco.js – Client.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
2
67
3
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\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 Illuminate\Support\Facades\Redis;
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)
{
$cacheKey = $this->getRateLimitCacheKey();
$cachedRetryAfter = Redis::get($cacheKey);
if (is_string($cachedRetryAfter) && is_numeric($cachedRetryAfter)) {
throw new RateLimitException(
'Hubspot rate limit (cached circuit-breaker)',
(int) $cachedRetryAfter,
);
}
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
Redis::setex($cacheKey, $retryAfter, (string) $retryAfter);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'policy' => $this->parsePolicy($e),
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
private function getRateLimitCacheKey(): string
{
return sprintf('hubspot:ratelimit:portal:%d', $this->config->getId());
}
public function isHubspotRateLimit(Throwable $e): bool
{
if ($e instanceof BadRequest
|| $e instanceof DealApiException
|| $e instanceof ContactApiException
|| $e instanceof CompanyApiException
|| $e instanceof \GuzzleHttp\Exception\RequestException
) {
return (int) $e->getCode() === 429;
}
return false;
}
public function parseRetryAfter(Throwable $e): int
{
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;
}
}
$policy = $this->parsePolicy($e);
if ($policy === 'TEN_SECONDLY_ROLLING') {
return 10;
}
if ($policy === 'SECONDLY') {
return 1;
}
if ($policy === 'DAILY_LIMIT') {
return 600;
}
$this->log->warning('[Hubspot] No retry-after header or policy name found, using default', [
'exception_class' => get_class($e),
]);
return 10;
}
public function parsePolicy(Throwable $e): ?string
{
if (! method_exists($e, 'getResponseBody')) {
return null;
}
$body = $e->getResponseBody();
if (is_string($body)) {
$body = json_decode($body, true) ?? [];
}
if (! is_array($body)) {
return null;
}
$policy = $body['policyName'] ?? $body['policy'] ?? $body['context']['policyName'] ?? null;
return is_string($policy) ? strtoupper($policy) : null;
}
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') {
return $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
return $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
}
/**
* @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 (RateLimitException $e) {
// throw $e;
} 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);
}
}
Show Replace Field
Search History
Received 429 from API
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case...
|
[{"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":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"67","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"3","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\\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\\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 Illuminate\\Support\\Facades\\Redis;\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\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Reacts to a rate limits (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 $cacheKey = $this->getRateLimitCacheKey();\n\n $cachedRetryAfter = Redis::get($cacheKey);\n if (is_string($cachedRetryAfter) && is_numeric($cachedRetryAfter)) {\n throw new RateLimitException(\n 'Hubspot rate limit (cached circuit-breaker)',\n (int) $cachedRetryAfter,\n );\n }\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n Redis::setex($cacheKey, $retryAfter, (string) $retryAfter);\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 'policy' => $this->parsePolicy($e),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n private function getRateLimitCacheKey(): string\n {\n return sprintf('hubspot:ratelimit:portal:%d', $this->config->getId());\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n if ($e instanceof BadRequest\n || $e instanceof DealApiException\n || $e instanceof ContactApiException\n || $e instanceof CompanyApiException\n || $e instanceof \\GuzzleHttp\\Exception\\RequestException\n ) {\n return (int) $e->getCode() === 429;\n }\n\n return false;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n \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 $policy = $this->parsePolicy($e);\n if ($policy === 'TEN_SECONDLY_ROLLING') {\n return 10;\n }\n if ($policy === 'SECONDLY') {\n return 1;\n }\n if ($policy === 'DAILY_LIMIT') {\n return 600;\n }\n\n $this->log->warning('[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 parsePolicy(Throwable $e): ?string\n {\n if (! method_exists($e, 'getResponseBody')) {\n return null;\n }\n\n $body = $e->getResponseBody();\n if (is_string($body)) {\n $body = json_decode($body, true) ?? [];\n }\n\n if (! is_array($body)) {\n return null;\n }\n\n $policy = $body['policyName'] ?? $body['policy'] ?? $body['context']['policyName'] ?? null;\n\n return is_string($policy) ? strtoupper($policy) : null;\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 return $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n return $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\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 (RateLimitException $e) {\n// throw $e;\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\\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 Illuminate\\Support\\Facades\\Redis;\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\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Reacts to a rate limits (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 $cacheKey = $this->getRateLimitCacheKey();\n\n $cachedRetryAfter = Redis::get($cacheKey);\n if (is_string($cachedRetryAfter) && is_numeric($cachedRetryAfter)) {\n throw new RateLimitException(\n 'Hubspot rate limit (cached circuit-breaker)',\n (int) $cachedRetryAfter,\n );\n }\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n Redis::setex($cacheKey, $retryAfter, (string) $retryAfter);\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 'policy' => $this->parsePolicy($e),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n private function getRateLimitCacheKey(): string\n {\n return sprintf('hubspot:ratelimit:portal:%d', $this->config->getId());\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n if ($e instanceof BadRequest\n || $e instanceof DealApiException\n || $e instanceof ContactApiException\n || $e instanceof CompanyApiException\n || $e instanceof \\GuzzleHttp\\Exception\\RequestException\n ) {\n return (int) $e->getCode() === 429;\n }\n\n return false;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n \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 $policy = $this->parsePolicy($e);\n if ($policy === 'TEN_SECONDLY_ROLLING') {\n return 10;\n }\n if ($policy === 'SECONDLY') {\n return 1;\n }\n if ($policy === 'DAILY_LIMIT') {\n return 600;\n }\n\n $this->log->warning('[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 parsePolicy(Throwable $e): ?string\n {\n if (! method_exists($e, 'getResponseBody')) {\n return null;\n }\n\n $body = $e->getResponseBody();\n if (is_string($body)) {\n $body = json_decode($body, true) ?? [];\n }\n\n if (! is_array($body)) {\n return null;\n }\n\n $policy = $body['policyName'] ?? $body['policy'] ?? $body['context']['policyName'] ?? null;\n\n return is_string($policy) ? strtoupper($policy) : null;\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 return $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n return $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\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 (RateLimitException $e) {\n// throw $e;\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":"Show Replace Field","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"Received 429 from API","depth":4,"on_screen":true,"value":"Received 429 from API","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"on_screen":false,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-8267411831603095084
|
5225837844252985444
|
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
2
67
3
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\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 Illuminate\Support\Facades\Redis;
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)
{
$cacheKey = $this->getRateLimitCacheKey();
$cachedRetryAfter = Redis::get($cacheKey);
if (is_string($cachedRetryAfter) && is_numeric($cachedRetryAfter)) {
throw new RateLimitException(
'Hubspot rate limit (cached circuit-breaker)',
(int) $cachedRetryAfter,
);
}
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
Redis::setex($cacheKey, $retryAfter, (string) $retryAfter);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'policy' => $this->parsePolicy($e),
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
private function getRateLimitCacheKey(): string
{
return sprintf('hubspot:ratelimit:portal:%d', $this->config->getId());
}
public function isHubspotRateLimit(Throwable $e): bool
{
if ($e instanceof BadRequest
|| $e instanceof DealApiException
|| $e instanceof ContactApiException
|| $e instanceof CompanyApiException
|| $e instanceof \GuzzleHttp\Exception\RequestException
) {
return (int) $e->getCode() === 429;
}
return false;
}
public function parseRetryAfter(Throwable $e): int
{
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;
}
}
$policy = $this->parsePolicy($e);
if ($policy === 'TEN_SECONDLY_ROLLING') {
return 10;
}
if ($policy === 'SECONDLY') {
return 1;
}
if ($policy === 'DAILY_LIMIT') {
return 600;
}
$this->log->warning('[Hubspot] No retry-after header or policy name found, using default', [
'exception_class' => get_class($e),
]);
return 10;
}
public function parsePolicy(Throwable $e): ?string
{
if (! method_exists($e, 'getResponseBody')) {
return null;
}
$body = $e->getResponseBody();
if (is_string($body)) {
$body = json_decode($body, true) ?? [];
}
if (! is_array($body)) {
return null;
}
$policy = $body['policyName'] ?? $body['policy'] ?? $body['context']['policyName'] ?? null;
return is_string($policy) ? strtoupper($policy) : null;
}
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') {
return $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
return $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
}
/**
* @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 (RateLimitException $e) {
// throw $e;
} 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);
}
}
Show Replace Field
Search History
Received 429 from API
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case...
|
17391
|
NULL
|
NULL
|
NULL
|
|
19326
|
829
|
15
|
2026-05-11T12:42:44.566402+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778503364566_m2.jpg...
|
Firefox
|
Comparing master...JY-20725-handle-HS-search-rate- Comparing master...JY-20725-handle-HS-search-rate-limit · jiminny/app — Work...
|
True
|
github.com/jiminny/app/compare/JY-20725-handle-HS- github.com/jiminny/app/compare/JY-20725-handle-HS-search-rate-limit?expand=1...
|
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
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
Comparing master...JY-20725-handle-HS-search-rate-limit · jiminny/app
Comparing master...JY-20725-handle-HS-search-rate-limit · jiminny/app
Close tab
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 (33)
Pull requests
(
33
)...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.3570479,"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.37034574,"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.3570479,"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.37034574,"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.3570479,"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.37034574,"top":0.12849163,"width":0.16140293,"height":0.010774142},"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,"bounds":{"left":0.3570479,"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":"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,"bounds":{"left":0.37034574,"top":0.16121309,"width":0.4644282,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Comparing master...JY-20725-handle-HS-search-rate-limit · jiminny/app","depth":4,"bounds":{"left":0.3570479,"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":true},{"role":"AXStaticText","text":"Comparing master...JY-20725-handle-HS-search-rate-limit · jiminny/app","depth":5,"bounds":{"left":0.37034574,"top":0.19393456,"width":0.1263298,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.42436835,"top":0.18994413,"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.35987368,"top":0.21707901,"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.35987368,"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.37084442,"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.38198137,"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.39311835,"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.40425533,"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":"AXLink","text":"Skip to content","depth":6,"bounds":{"left":0.43666887,"top":0.0518755,"width":0.0003324468,"height":0.0007980846},"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,"bounds":{"left":0.43666887,"top":0.05347167,"width":0.0029920214,"height":0.21468475},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"bounds":{"left":0.44198802,"top":0.06464485,"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":"AXLink","text":"Homepage (g then d)","depth":9,"bounds":{"left":0.4566157,"top":0.06464485,"width":0.010638298,"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":"jiminny","depth":12,"bounds":{"left":0.46991357,"top":0.06464485,"width":0.018949468,"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","depth":14,"bounds":{"left":0.47190824,"top":0.07063048,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"bounds":{"left":0.49384972,"top":0.06464485,"width":0.017785905,"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":"app","depth":14,"bounds":{"left":0.49584442,"top":0.07063048,"width":0.008477394,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"bounds":{"left":0.81698805,"top":0.06464485,"width":0.06565824,"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":"Type","depth":12,"bounds":{"left":0.82928854,"top":0.07063048,"width":0.011801862,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"bounds":{"left":0.8424202,"top":0.07222666,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"bounds":{"left":0.84640956,"top":0.07063048,"width":0.021276595,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"bounds":{"left":0.88464093,"top":0.06464485,"width":0.010638298,"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":"Open Copilot…","depth":9,"bounds":{"left":0.8949468,"top":0.06464485,"width":0.008643617,"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":"AXMenuButton","text":"Create new...","depth":9,"bounds":{"left":0.9115692,"top":0.06464485,"width":0.01662234,"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":"All issues(g then i)","depth":9,"bounds":{"left":0.93085104,"top":0.06464485,"width":0.010638298,"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":"All pull requests","depth":9,"bounds":{"left":0.94414896,"top":0.06464485,"width":0.010638298,"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":"All repositories","depth":9,"bounds":{"left":0.9574468,"top":0.06464485,"width":0.010638298,"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":"You have unread notifications(g then n)","depth":9,"bounds":{"left":0.97074467,"top":0.06464485,"width":0.010638298,"height":0.025538707},"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,"bounds":{"left":0.9840425,"top":0.06464485,"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":"Repository navigation","depth":9,"bounds":{"left":0.43633643,"top":0.051077414,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"bounds":{"left":0.43633643,"top":0.05387071,"width":0.0787899,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"bounds":{"left":0.44198802,"top":0.09936153,"width":0.025099734,"height":0.026336791},"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,"bounds":{"left":0.45262632,"top":0.10574621,"width":0.011801862,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (33)","depth":12,"bounds":{"left":0.46974733,"top":0.09936153,"width":0.05518617,"height":0.026336791},"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,"bounds":{"left":0.48105052,"top":0.10574621,"width":0.027925532,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"bounds":{"left":0.51230055,"top":0.113727055,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"33","depth":14,"bounds":{"left":0.5152925,"top":0.113727055,"width":0.005817819,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"bounds":{"left":0.52111036,"top":0.113727055,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8265179401618908055
|
-4430348709385301366
|
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
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
Comparing master...JY-20725-handle-HS-search-rate-limit · jiminny/app
Comparing master...JY-20725-handle-HS-search-rate-limit · jiminny/app
Close tab
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 (33)
Pull requests
(
33
)...
|
19323
|
NULL
|
NULL
|
NULL
|
|
17063
|
764
|
2
|
2026-05-11T10:02:11.886126+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778493731886_m1.jpg...
|
PhpStorm
|
faVsco.js – HandleHubspotRateLimitTest.php
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp<lihl••APP (-zsh)83DOCKERDEV (docker)₴82APP (-zsh)worker-analytics:worker-analytics_00: stoppedworker-crm-update:worker-crm-update_00: stoppedworker-download:worker-download_00: stoppedworker-nudges:worker-nudges_00:stoppedartisan-schedule:artisan-schedule_00:stoppedworker-emails:worker-emails_00: stoppedworker:worker_00: stoppedworker-calendar:worker-calendar_00:stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedworker-crm-sync:worker-crm-sync_00:stoppedworker-audio:worker-audio_00: stoppedworker-conferences:worker-conferences_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: started-zshWhat's next:Try Docker Debug for seamless, persistent debugging tools in any container or image + docker debug docker_lamp_1Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $|§ Support Daily - in 1h 58 mA-zsh885100% C8• Mon 11 May 13:02:11181screenpipe"O 86APP...
|
NULL
|
-8265041118146373714
|
NULL
|
click
|
ocr
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp<lihl••APP (-zsh)83DOCKERDEV (docker)₴82APP (-zsh)worker-analytics:worker-analytics_00: stoppedworker-crm-update:worker-crm-update_00: stoppedworker-download:worker-download_00: stoppedworker-nudges:worker-nudges_00:stoppedartisan-schedule:artisan-schedule_00:stoppedworker-emails:worker-emails_00: stoppedworker:worker_00: stoppedworker-calendar:worker-calendar_00:stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedworker-crm-sync:worker-crm-sync_00:stoppedworker-audio:worker-audio_00: stoppedworker-conferences:worker-conferences_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: started-zshWhat's next:Try Docker Debug for seamless, persistent debugging tools in any container or image + docker debug docker_lamp_1Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $|§ Support Daily - in 1h 58 mA-zsh885100% C8• Mon 11 May 13:02:11181screenpipe"O 86APP...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
24661
|
1029
|
0
|
2026-05-12T09:32:24.083163+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778578344083_m2.jpg...
|
PhpStorm
|
faVsco.js – console [PROD]
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormViewINavigareCodeLaravelKeractorJOOISWindo PhpStormViewINavigareCodeLaravelKeractorJOOISWindowFV faVsco.js?9 JY-20725-handle-HS-search-rate-limitProiect vC) AutomatedReportGeneratea.onpPlanhatService.php= aitattributes•.gitignore.php-cs-fixer.cachephp.php-cs-fixer.dist.php© AutomatedReportResult.php x<?phpnamespace Jiminny Modelspip.onpstorm.meta.pnpE.phpunit.result.cacheE.prettierignore=.windsurfrules• use ...pnp _lde_nelper.pnppnp_lde_nelper._models.onpphp aruisancomposer.soncomposer.lockudependencv-checker.lson& dev.isonE ids.txt=infection.ison.distM+INSTALL.mdMAINTERNAL WERHOOK SETUP.N=liminny storaaeMtlicenses.mdM Makefile0 package-lock.json=ohostan.neon.distE phpstan-baseline.neon<> phpunit.xmlT raw sal_query.sqlML PEADME md< sonar-project.propertiesE test.py<> Untitled Diagram.xmllis votur confin icServices+,o,cv O DatabaseV dEU&console 3 sv Aliminnv@localhostAHSocal 1s 665 msASFv APROD« console# STAGINGIconsole…Docker* Jiminnu Models Automatedreportresult* doropertu int 51d* doropertu strind suuld* doropertu int Sreoort id* doropertu strinalnul Sname* Goropertu int Sstatus* Goropertu int Sreason* @property string Smedia_type* anronentu intinur Snarent 7o* @property arraylnull $payload* Anronentu arraulnull Srecnonso* @property Carbon|null Srequested_at* @property Carbon/null $generated_at* doroperty Carbon null Ssent at* @property Carbon|null $created_at* dohopenc carboninuce supoarea_at* donoрenuehed oiminny rodels Aucomareukeport srepora* doventered Aucomareareportkesulc null sourent* @nronertu-read \Illuminate\Database\Eloquent\Collection<int, AutomatedReportResult> Schildrenclass AutomatedReportResult extends ModelOutoutitiminny automated renort resultsfw 1rowvDidIouuid WUTD with time-low and time-hiah swanned)l(• report idI nameI media typeparent idW status( reason1 payloadI responseM requested atM aenenated at"suppont Dally • In zn 20m100% 5• Tue 12 May 12:32:23HandleHubspotRateLimitTest vFixing Automated Rep+0 ..A8v1V1AY=custom.log=laravel.logA SF (jiminny@localhost]4 HS_local [jiminny@localhost]« console [PROD] X#console leuyA console [STAGING]=643644[PHONE]49|65165.659= 65%[658So jiminny040 A1 A40 V 64 ^select * from activities where crm_configuration_ id = 537 and provider = 'aircall'ana account1d = 1y005058 order by updacedar descselect * from contacts where crm_confiquration id = 537 and id = 35957759selecc * rrom accouncs where crm contlquracion 10 = 55/ and 10 = 17005058select * from automated_report_results where 1d = 19761select * from automated reports where 1d = 5835select * from activity_searches where id = 87714:select * from activity search_filters where activity search 1d = 877141SELEC * FROM activities WHERE uuid to bind 88274672-202d-4162-9d04-73ff5f0566a9' = uuildlor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid:SELECT * FROM crm_configurations WHERE provider = 'hubspot';select * from rate Limits:select * from autolated_report_results where media type = 'pdf' and status = 2and id IN (18, 1872);select * from automated_reports where id = 54;SELECT * FROM users WHERE id IN (24623, 29443, 29613):SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;ПШ 11cascadePlanhat Event PlaybadInoughttor is>Thouaht for 3slAnalysisRoot Cause:SendReport.Job.oho:80 calls getMediaPath(Sreport) which returns null when odf url is missina from the responsePassing null to Storage::disk()->exists() triggers the Flysystem type error1. Report has media type: pdt but responsel pdt url is null2. getPdfUrl() returns null (line 374-375 in AutomatedReportResult.php)getMediaPath() returns null (line 2266-2281 in AutomatedReportsService.php)Cronjob Behavior: The send cronjob (AutomatedReportsSendCommand. php:58 ) uses getGeneratedNotSentResults()which filters• Reiect all | Accept allAsk anything (2 +L)<> Code SWE-1.6@: -# Q HEAФ1870822fa41h-afd3-43a0-a248-86h0e36f3131Coaching Profiles - 6 - 12 Apr 2026 - Client Success. UK Salesodf<null>F"team Ed":1,"request id":"822fa41b-afd3-43a9-a248-86b003663131","nepont type":"coaching profiles", "media types"AUodf" "podcast™), "from date":"2026-04-06700:00:00+00:00" "to date":"2026-04-12723:59:59+00:00", "group Eds"A191,21l"cali deal stage"Hlül,"cunrent deal stage"aul"deal minE"request Sidw:W822faLib-afd3-43a9-a228-86h0036f3131W,"status"•"compieted™ "timestamo":W2026-04-13101411848.648399-00:004.W93 UNWW83AVViiminny.cilient-dataV/Sf0f4810-7077-4086-8f69-93429ae4d70hV/renontsVB22faLib-afd3-43a9-a228-86h0e36f331 MD™, "nenont tvne":"coachine2026-04-13 01:00•572026-04-13 01+11•49W Windsurf Toams 664-24UTF.A...
|
NULL
|
-8260437485268984310
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormViewINavigareCodeLaravelKeractorJOOISWindo PhpStormViewINavigareCodeLaravelKeractorJOOISWindowFV faVsco.js?9 JY-20725-handle-HS-search-rate-limitProiect vC) AutomatedReportGeneratea.onpPlanhatService.php= aitattributes•.gitignore.php-cs-fixer.cachephp.php-cs-fixer.dist.php© AutomatedReportResult.php x<?phpnamespace Jiminny Modelspip.onpstorm.meta.pnpE.phpunit.result.cacheE.prettierignore=.windsurfrules• use ...pnp _lde_nelper.pnppnp_lde_nelper._models.onpphp aruisancomposer.soncomposer.lockudependencv-checker.lson& dev.isonE ids.txt=infection.ison.distM+INSTALL.mdMAINTERNAL WERHOOK SETUP.N=liminny storaaeMtlicenses.mdM Makefile0 package-lock.json=ohostan.neon.distE phpstan-baseline.neon<> phpunit.xmlT raw sal_query.sqlML PEADME md< sonar-project.propertiesE test.py<> Untitled Diagram.xmllis votur confin icServices+,o,cv O DatabaseV dEU&console 3 sv Aliminnv@localhostAHSocal 1s 665 msASFv APROD« console# STAGINGIconsole…Docker* Jiminnu Models Automatedreportresult* doropertu int 51d* doropertu strind suuld* doropertu int Sreoort id* doropertu strinalnul Sname* Goropertu int Sstatus* Goropertu int Sreason* @property string Smedia_type* anronentu intinur Snarent 7o* @property arraylnull $payload* Anronentu arraulnull Srecnonso* @property Carbon|null Srequested_at* @property Carbon/null $generated_at* doroperty Carbon null Ssent at* @property Carbon|null $created_at* dohopenc carboninuce supoarea_at* donoрenuehed oiminny rodels Aucomareukeport srepora* doventered Aucomareareportkesulc null sourent* @nronertu-read \Illuminate\Database\Eloquent\Collection<int, AutomatedReportResult> Schildrenclass AutomatedReportResult extends ModelOutoutitiminny automated renort resultsfw 1rowvDidIouuid WUTD with time-low and time-hiah swanned)l(• report idI nameI media typeparent idW status( reason1 payloadI responseM requested atM aenenated at"suppont Dally • In zn 20m100% 5• Tue 12 May 12:32:23HandleHubspotRateLimitTest vFixing Automated Rep+0 ..A8v1V1AY=custom.log=laravel.logA SF (jiminny@localhost]4 HS_local [jiminny@localhost]« console [PROD] X#console leuyA console [STAGING]=643644[PHONE]49|65165.659= 65%[658So jiminny040 A1 A40 V 64 ^select * from activities where crm_configuration_ id = 537 and provider = 'aircall'ana account1d = 1y005058 order by updacedar descselect * from contacts where crm_confiquration id = 537 and id = 35957759selecc * rrom accouncs where crm contlquracion 10 = 55/ and 10 = 17005058select * from automated_report_results where 1d = 19761select * from automated reports where 1d = 5835select * from activity_searches where id = 87714:select * from activity search_filters where activity search 1d = 877141SELEC * FROM activities WHERE uuid to bind 88274672-202d-4162-9d04-73ff5f0566a9' = uuildlor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid:SELECT * FROM crm_configurations WHERE provider = 'hubspot';select * from rate Limits:select * from autolated_report_results where media type = 'pdf' and status = 2and id IN (18, 1872);select * from automated_reports where id = 54;SELECT * FROM users WHERE id IN (24623, 29443, 29613):SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;ПШ 11cascadePlanhat Event PlaybadInoughttor is>Thouaht for 3slAnalysisRoot Cause:SendReport.Job.oho:80 calls getMediaPath(Sreport) which returns null when odf url is missina from the responsePassing null to Storage::disk()->exists() triggers the Flysystem type error1. Report has media type: pdt but responsel pdt url is null2. getPdfUrl() returns null (line 374-375 in AutomatedReportResult.php)getMediaPath() returns null (line 2266-2281 in AutomatedReportsService.php)Cronjob Behavior: The send cronjob (AutomatedReportsSendCommand. php:58 ) uses getGeneratedNotSentResults()which filters• Reiect all | Accept allAsk anything (2 +L)<> Code SWE-1.6@: -# Q HEAФ1870822fa41h-afd3-43a0-a248-86h0e36f3131Coaching Profiles - 6 - 12 Apr 2026 - Client Success. UK Salesodf<null>F"team Ed":1,"request id":"822fa41b-afd3-43a9-a248-86b003663131","nepont type":"coaching profiles", "media types"AUodf" "podcast™), "from date":"2026-04-06700:00:00+00:00" "to date":"2026-04-12723:59:59+00:00", "group Eds"A191,21l"cali deal stage"Hlül,"cunrent deal stage"aul"deal minE"request Sidw:W822faLib-afd3-43a9-a228-86h0036f3131W,"status"•"compieted™ "timestamo":W2026-04-13101411848.648399-00:004.W93 UNWW83AVViiminny.cilient-dataV/Sf0f4810-7077-4086-8f69-93429ae4d70hV/renontsVB22faLib-afd3-43a9-a228-86h0e36f331 MD™, "nenont tvne":"coachine2026-04-13 01:00•572026-04-13 01+11•49W Windsurf Toams 664-24UTF.A...
|
24660
|
NULL
|
NULL
|
NULL
|
|
2167
|
99
|
3
|
2026-05-07T11:03:57.628387+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778151837628_m1.jpg...
|
iTerm2
|
NULL
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp(aholSupport Daily • in 57 mA100% <478DEV (docker)DOCKERLast login: Thu May*1DEV (docker)182APP (-zsh)-zsh|7 09:44:56 on ttys006Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parentsPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parentslukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20773-fix-automated-reports-user-pilot-tracking) $ devroot@docker_lamp_1:/home/jiminny# 0• 84|screenpipe"•$5-zshThu 7 May 14:03:57T81₴6DEV...
|
NULL
|
-8259126480402266253
|
NULL
|
click
|
ocr
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp(aholSupport Daily • in 57 mA100% <478DEV (docker)DOCKERLast login: Thu May*1DEV (docker)182APP (-zsh)-zsh|7 09:44:56 on ttys006Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parentsPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parentslukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20773-fix-automated-reports-user-pilot-tracking) $ devroot@docker_lamp_1:/home/jiminny# 0• 84|screenpipe"•$5-zshThu 7 May 14:03:57T81₴6DEV...
|
2165
|
NULL
|
NULL
|
NULL
|
|
24126
|
1009
|
44
|
2026-05-12T08:44:34.957782+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778575474957_m2.jpg...
|
Firefox
|
TypeError: League\Flysystem\Filesystem::has(): Arg 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 — Work...
|
True
|
jiminny.sentry.io/issues/6873095751?project=82419
|
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
Close tab
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 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
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
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Toggle organization menu
Issues
Issues
Explore
Explore
Dashboards
Dashboards
Monitors
Monitors
Settings
Settings
Try Business...
|
[{"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":true},{"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":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.087789305,"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":"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":"AXButton","text":"Unnamed Group","depth":4,"bounds":{"left":0.0028257978,"top":0.15123703,"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":"Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app","depth":4,"bounds":{"left":0.0028257978,"top":0.17478053,"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":"Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app","depth":5,"bounds":{"left":0.015957447,"top":0.18635276,"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.0,"top":0.207502,"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.21907422,"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.24022347,"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.25179568,"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.0,"top":0.27294493,"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.28451717,"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.0,"top":0.3056664,"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.013297873,"top":0.31723863,"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.0,"top":0.33838788,"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.3499601,"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.0,"top":0.37110934,"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.013297873,"top":0.38268158,"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.0,"top":0.4038308,"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.41540304,"width":0.07646277,"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.0,"top":0.4365523,"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.013297873,"top":0.4481245,"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.0,"top":0.46927375,"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.013297873,"top":0.48084596,"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.0,"top":0.5019952,"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.013297873,"top":0.51356745,"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.0,"top":0.53471667,"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.5462889,"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.0,"top":0.5674381,"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":"Jiminny","depth":5,"bounds":{"left":0.013297873,"top":0.57901037,"width":0.013131649,"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.6017558,"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":"AXLink","text":"Skip to main content","depth":8,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to main content","depth":9,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Toggle organization menu","depth":11,"bounds":{"left":0.08643617,"top":0.059856344,"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,"is_expanded":false},{"role":"AXLink","text":"Issues","depth":12,"bounds":{"left":0.0809508,"top":0.09736632,"width":0.021609042,"height":0.050678372},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":14,"bounds":{"left":0.0866024,"top":0.13048683,"width":0.010305851,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore","depth":12,"bounds":{"left":0.0809508,"top":0.14804469,"width":0.021609042,"height":0.050678372},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore","depth":14,"bounds":{"left":0.08577128,"top":0.1811652,"width":0.011968086,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Dashboards","depth":12,"bounds":{"left":0.0809508,"top":0.19872306,"width":0.021609042,"height":0.05027933},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Dashboards","depth":14,"bounds":{"left":0.08211436,"top":0.23184358,"width":0.019281914,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Monitors","depth":12,"bounds":{"left":0.0809508,"top":0.2490024,"width":0.021609042,"height":0.050678372},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Monitors","depth":14,"bounds":{"left":0.084773935,"top":0.2821229,"width":0.013962766,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"bounds":{"left":0.0809508,"top":0.29968077,"width":0.021609042,"height":0.050678372},"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,"bounds":{"left":0.08494016,"top":0.33280128,"width":0.013630319,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Try Business","depth":10,"bounds":{"left":0.08643617,"top":0.88667196,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_selected":false}]...
|
-8258467418951733669
|
-3457266480968943476
|
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
Close tab
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 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
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
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Toggle organization menu
Issues
Issues
Explore
Explore
Dashboards
Dashboards
Monitors
Monitors
Settings
Settings
Try Business...
|
24125
|
NULL
|
NULL
|
NULL
|
|
7842
|
349
|
9
|
2026-05-08T09:35:13.789045+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-08/1778 /Users/lukas/.screenpipe/data/data/2026-05-08/1778232913789_m1.jpg...
|
Firefox
|
Jy 20493 smart instant nudge pre filtering by niko Jy 20493 smart instant nudge pre filtering by nikolaybiaivanov · Pull Request #12053 · jiminny/app — Work...
|
True
|
github.com/jiminny/app/pull/12053/changes#r3207759 github.com/jiminny/app/pull/12053/changes#r3207759305...
|
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
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST [URL_WITH_CREDENTIALS] -4,16 +4,17 @@445namespace Jiminny\Component\Nudge\Job;5namespace Jiminny\Component\Nudge\Job;667+use Carbon\Carbon;7use Illuminate\Bus\Queueable;8use Illuminate\Bus\Queueable;8use Illuminate\Contracts\Queue\ShouldQueue;9use Illuminate\Contracts\Queue\ShouldQueue;9-use Illuminate\Database\Eloquent\Builder;10use Illuminate\Foundation\Bus\Dispatchable;10use Illuminate\Foundation\Bus\Dispatchable;11use Illuminate\Queue\InteractsWithQueue;11use Illuminate\Queue\InteractsWithQueue;12use Illuminate\Queue\SerializesModels;12use Illuminate\Queue\SerializesModels;13use Illuminate\Support\Facades\Log;13use Illuminate\Support\Facades\Log;14use Jiminny\Component\Queue\Constants;14use Jiminny\Component\Queue\Constants;15use Jiminny\Models\Activity;15use Jiminny\Models\Activity;16use Jiminny\Models\Activity\Search;16use Jiminny\Models\Activity\Search;17+use Jiminny\Models\Activity\SearchFilter;17use Jiminny\Models\Nudge;18use Jiminny\Models\Nudge;18use Jiminny\Models\Team;19use Jiminny\Models\Team;1920@@ -34,37 +35,201 @@343535public function handle(): void36public function handle(): void36 {37 {37-/** @var Activity $activity */38+$activity = Activity::with(['user.group'])->uuid($this->activityUuid, false)->firstOrFail();38-$activity = Activity::with(['user'])->uuid($this->activityUuid, false)->firstOrFail();39-40-/** @var Team $team */41$team = Team::with(['users'])->findOrFail($activity->user->team_id);39$team = Team::with(['users'])->findOrFail($activity->user->team_id);424043- Log::info(__METHOD__ . " Running for team $team->id.", [44-'activity_id' => $activity->id,45-'activity_uuid' => $this->activityUuid,46-'team_id' => $team->id,47- ]);48-49$usersIds = $team->users->pluck('id')->toArray();41$usersIds = $team->users->pluck('id')->toArray();504251-$searchesWithImmediateNudges = Activity\Search::with(['nudges'])43+$searchesWithImmediateNudges = Activity\Search::with([44+'nudges' => fn ($q) => $q->where('frequency', Nudge::FREQ_INSTANTLY),45+'filters',46+ ])52 ->whereIn('user_id', $usersIds)47 ->whereIn('user_id', $usersIds)53- ->whereHas('nudges', function (Builder $query) {48+ ->whereHas('nudges', fn ($q) => $q->where('frequency', Nudge::FREQ_INSTANTLY))54-$query->where('frequency', Nudge::FREQ_INSTANTLY);49+ ->get();55- })->get();50+51+$totalSearches = $searchesWithImmediateNudges->count();52+$skippedCount = 0;53+54+$searchesWithImmediateNudges->each(function (Search $search) use ($activity, &$skippedCount): void {55+$matchResult = $this->activityMightMatchSearch($activity, $search);565657-$searchesWithImmediateNudges->each(function (Search $search): void {57+if (! $matchResult['matches']) {58-$search->nudges->each(function (Nudge $nudge): void {58+$skippedCount++;59-// Filter only nudges that are set to be sent instantly59+ Log::info('Pre-filter skipped nudge dispatch', [60-if ($nudge->frequency === Nudge::FREQ_INSTANTLY) {60+'activity_uuid' => $activity->getUuid(),61- Log::info("Dispatching ProcessNudgeSearchJob for nudge $nudge->id.");61+'search_id' => $search->getId(),62+'mismatched_filter' => $matchResult['mismatch_reason'],63+'filter_value' => $matchResult['filter_value'],64+ ]);626563- ProcessNudgeSearchJob::dispatch($nudge);66+return;67+ }646865- Log::info("ProcessNudgeSearchJob dispatched for nudge $nudge->id.");69+$search->nudges->each(fn ($nudge) => ProcessNudgeSearchJob::dispatch($nudge));66- }67- });68 });70 });71+72+if ($totalSearches > 0) {73+ Log::info('Nudge pre-filter results', [74+'activity_uuid' => $activity->getUuid(),75+'total_searches' => $totalSearches,76+'skipped' => $skippedCount,77+'dispatched' => $totalSearches - $skippedCount,78+'skip_rate' => round(($skippedCount / $totalSearches) * 100, 2) . '%',79+ ]);80+ }81+ }82+83+private function activityMightMatchSearch(Activity $activity, Search $search): array84+ {85+foreach ($search->filters as $filter) {86+$filterName = $filter->getFilterProperty();87+88+$result = match ($filterName) {89+'group_id' => $this->checkGroupId($activity, $filter),90+'user_id' => $this->checkUserId($activity, $filter),91+'channel_id' => $this->checkChannelId($activity, $filter),92+'provider_id' => $this->checkProviderId($activity, $filter),93+'category_id' => $this->checkCategoryId($activity, $filter),94+'min_duration' => $this->checkMinDuration($activity, $filter),95+'max_duration' => $this->checkMaxDuration($activity, $filter),96+'not_logged' => $this->checkNotLogged($activity, $filter),97+'only_recorded' => $this->checkOnlyRecorded($activity, $filter),98+'languages' => $this->checkLanguages($activity, $filter),99+'stage_id' => $this->checkStageId($activity, $filter),100+'start_date' => $this->checkStartDate($activity, $filter),101+'end_date' => $this->checkEndDate($activity, $filter),102+default => null, // Unknown filter - can't pre-check, assume might match103+ };104+105+if ($result === false) {106+return [107+'matches' => false,108+'mismatch_reason' => $filterName,109+'filter_value' => $filter->getFilterValue(),110+ ];111+ }112+ }113+114+return ['matches' => true];115+ }116+117+private function checkGroupId(Activity $activity, SearchFilter $filter): ?bool118+ {119+$groupUuid = $activity->user->getGroup()?->getUuid();120+if ($groupUuid === null) {121+return null;122+ }123+124+return $filter->getFilterValue() === $groupUuid ? null : false;125+ }126+127+private function checkUserId(Activity $activity, SearchFilter $filter): ?bool128+ {129+return $filter->getFilterValue() === $activity->user->getUuid() ? null : false;130+ }131+132+private function checkChannelId(Activity $activity, SearchFilter $filter): ?bool133+ {134+return $filter->getFilterValue() === $activity->getType() ? null : false;135+ }136+137+private function checkProviderId(Activity $activity, SearchFilter $filter): ?bool138+ {139+return $filter->getFilterValue() === $activity->getProvider() ? null : false;140+ }141+142+private function checkCategoryId(Activity $activity, SearchFilter $filter): ?bool143+ {144+$categoryId = $activity->getCategory()?->getUuid();145+if ($categoryId === null) {146+return null;147+ }148+149+return $filter->getFilterValue() === $categoryId ? null : false;150+ }151+152+private function checkMinDuration(Activity $activity, SearchFilter $filter): ?bool153+ {154+return $activity->getDuration() >= (float) $filter->getFilterValue() ? null : false;155+ }156+157+private function checkMaxDuration(Activity $activity, SearchFilter $filter): ?bool158+ {159+return $activity->getDuration() <= (float) $filter->getFilterValue() ? null : false;160+ }161+162+private function checkNotLogged(Activity $activity, SearchFilter $filter): ?bool163+ {164+if (! $filter->getFilterValue()) {165+return null;166+ }167+168+$isLogged = $activity->getCrmProviderId() !== null;169+$isInternal = $activity->isInternal();170+171+return (! $isLogged || $isInternal) ? null : false;172+ }173+174+private function checkOnlyRecorded(Activity $activity, SearchFilter $filter): ?bool175+ {176+$filterValue = (int) $filter->getFilterValue();177+$hasRecording = $activity->recording_state !== Activity::RECORDING_OFF;178+179+return match ($filterValue) {180+1 => $hasRecording ? null : false, // Only recorded181+2 => ! $hasRecording ? null : false, // Only non-recorded182+default => null,183+ };184+ }185+186+private function checkStageId(Activity $activity, SearchFilter $filter): ?bool187+ {188+$stageId = $activity->getStage()?->getUuid();189+if ($stageId === null) {190+return null; // No stage, let ES handle191+ }192+193+return $filter->getFilterValue() === $stageId ? null : false;194+ }195+196+private function checkStartDate(Activity $activity, SearchFilter $filter): ?bool197+ {198+$startTime = $activity->getActualStartTime();199+if ($startTime === null) {200+return null;201+ }202+203+$filterDate = Carbon::parse($filter->getFilterValue());204+205+return $startTime->gte($filterDate) ? null : false;206+ }207+208+private function checkEndDate(Activity $activity, SearchFilter $filter): ?bool209+ {210+$endTime = $activity->getActualEndTime();211+if ($endTime === null) {212+return null;213+ }214+215+$filterDate = Carbon::parse($filter->getFilterValue())->endOfDay();216+217+return $endTime->lte($filterDate) ? null : false;218+ }219+220+private function checkLanguages(Activity $activity, SearchFilter $filter): ?bool221+ {222+$activityLanguage = $activity->getLanguageCode();223+if ($activityLanguage === null) {224+return null;225+ }226+227+// Filter values are always base language codes (e.g., 'en', 'fr').228+// Extract base code from activity locale (e.g., en_GB -> en) to match ES query behavior.229+// See LanguageFilterDefinition::getQueries() which uses regex: $language . '_[a-z]{2}'230+$activityLangCode = explode('_', $activityLanguage)[0];231+$filterLanguage = $filter->getFilterValue();232+233+return $activityLangCode === $filterLanguage ? null : false;69 }234 }70}235}</selection>” selected. Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
You said
I’m on page “<tabTitle>Jy 20493 smart instant nudge pre filtering by niko</tabTitle>” with “<selection>@@ -4,16 +4,17 @@445namespace Jiminny\Component\Nudge\Job;5namespace Jiminny\Component\Nudge\Job;667+use Carbon\Carbon;7use Illuminate\Bus\Queueable;8use Illuminate\Bus\Queueable;8use Illuminate\Contracts\Queue\ShouldQueue;9use Illuminate\Contracts\Queue\ShouldQueue;9-use Illuminate\Database\Eloquent\Builder;10use Illuminate\Foundation\Bus\Dispatchable;10use Illuminate\Foundation\Bus\Dispatchable;11use Illuminate\Queue\InteractsWithQueue;11use Illuminate\Queue\InteractsWithQueue;12use Illuminate\Queue\SerializesModels;12use Illuminate\Queue\SerializesModels;13use Illuminate\Support\Facades\Log;13use Illuminate\Support\Facades\Log;14use Jiminny\Component\Queue\Constants;14use Jiminny\Component\Queue\Constants;15use Jiminny\Models\Activity;15use Jiminny\Models\Activity;16use Jiminny\Models\Activity\Search;16use Jiminny\Models\Activity\Search;17+use Jiminny\Models\Activity\SearchFilter;17use Jiminny\Models\Nudge;18use Jiminny\Models\Nudge;18use Jiminny\Models\Team;19use Jiminny\Models\Team;1920@@ -34,37 +35,201 @@343535public function handle(): void36public function handle(): void36 {37 {37-/** @var Activity $activity */38+$activity = Activity::with(['user.group'])->uuid($this->activityUuid, false)->firstOrFail();38-$activity = Activity::with(['user'])->uuid($this->activityUuid, false)->firstOrFail();39-40-/** @var Team $team */41$team = Team::with(['users'])->findOrFail($activity->user->team_id);39$team = Team::with(['users'])->findOrFail($activity->user->team_id);424043- Log::info(__METHOD__ . " Running for team $team->id.", [44-'activity_id' => $activity->id,45-'activity_uuid' => $this->activityUuid,46-'team_id' => $team->id,47- ]);48-49$usersIds = $team->users->pluck('id')->toArray();41$usersIds = $team->users->pluck('id')->toArray();504251-$searchesWithImmediateNudges = Activity\Search::with(['nudges'])43+$searchesWithImmediateNudges = Activity\Search::with([44+'nudges' => fn ($q) => $q->where('frequency', Nudge::FREQ_INSTANTLY),45+'filters',46+ ])52 ->whereIn('user_id', $usersIds)47 ->whereIn('user_id', $usersIds)53- ->whereHas('nudges', function (Builder $query) {48+ ->whereHas('nudges', fn ($q) => $q->where('frequency', Nudge::FREQ_INSTANTLY))54-$query->where('frequency', Nudge::FREQ_INSTANTLY);49+ ->get();55- })->get();50+51+$totalSearches = $searchesWithImmediateNudges->count();52+$skippedCount = 0;53+54+$searchesWithImmediateNudges->each(function (Search $search) use ($activity, &$skippedCount): void {55+$matchResult = $this->activityMightMatchSearch($activity, $search);565657-$searchesWithImmediateNudges->each(function (Search $search): void {57+if (! $matchResult['matches']) {58-$search->nudges->each(function (Nudge $nudge): void {58+$skippedCount++;59-// Filter only nudges that are set to be sent instantly59+ Log::info('Pre-filter skipped nudge dispatch', [60-if ($nudge->frequency === Nudge::FREQ_INSTANTLY) {60+'activity_uuid' => $activity->getUuid(),61- Log::info("Dispatching ProcessNudgeSearchJob for nudge $nudge->id.");61+'search_id' => $search->getId(),62+'mismatched_filter' => $matchResult['mismatch_reason'],63+'filter_value' => $matchResult['filter_value'],64+ ]);626563- ProcessNudgeSearchJob::dispatch($nudge);66+return;67+ }646865- Log::info("ProcessNudgeSearchJob dispatched for nudge $nudge->id.");69+$search->nudges->each(fn ($nudge) => ProcessNudgeSearchJob::dispatch($nudge));66- }67- });68 });70 });71+72+if ($totalSearches > 0) {73+ Log::info('Nudge pre-filter results', [74+'activity_uuid' => $activity->getUuid(),75+'total_searches' => $totalSearches,76+'skipped' => $skippedCount,77+'dispatched' => $totalSearches - $skippedCount,78+'skip_rate' => round(($skippedCount / $totalSearches) * 100, 2) . '%',79+ ]);80+ }81+ }82+83+private function activityMightMatchSearch(Activity $activity, Search $search): array84+ {85+foreach ($search->filters as $filter) {86+$filterName = $filter->getFilterProperty();87+88+$result = match ($filterName) {89+'group_id' => $this->checkGroupId($activity, $filter),90+'user_id' => $this->checkUserId($activity, $filter),91+'channel_id' => $this->checkChannelId($activity, $filter),92+'provider_id' => $this->checkProviderId($activity, $filter),93+'category_id' => $this->checkCategoryId($activity, $filter),94+'min_duration' => $this->checkMinDuration($activity, $filter),95+'max_duration' => $this->checkMaxDuration($activity, $filter),96+'not_logged' => $this->checkNotLogged($activity, $filter),97+'only_recorded' => $this->checkOnlyRecorded($activity, $filter),98+'languages' => $this->checkLanguages($activity, $filter),99+'stage_id' => $this->checkStageId($activity, $filter),100+'start_date' => $this->checkStartDate($activity, $filter),101+'end_date' => $this->checkEndDate($activity, $filter),102+default => null, // Unknown filter - can't pre-check, assume might match103+ };104+105+if ($result === false) {106+return [107+'matches' => false,108+'mismatch_reason' => $filterName,109+'filter_value' => $filter->getFilterValue(),110+ ];111+ }112+ }113+114+return ['matches' => true];115+ }116+117+private function checkGroupId(Activity $activity, SearchFilter $filter): ?bool118+ {119+$groupUuid = $activity->user->getGroup()?->getUuid();120+if ($groupUuid === null) {121+return null;122+ }123+124+return $filter->getFilterValue() === $groupUuid ? null : false;125+ }126+127+private function checkUserId(Activity $activity, SearchFilter $filter): ?bool128+ {129+return $filter->getFilterValue() === $activity->user->getUuid() ? null : false;130+ }131+132+private function checkChannelId(Activity $activity, SearchFilter $filter): ?bool133+ {134+return $filter->getFilterValue() === $activity->getType() ? null : false;135+ }136+137+private function checkProviderId(Activity $activity, SearchFilter $filter): ?bool138+ {139+return $filter->getFilterValue() === $activity->getProvider() ? null : false;140+ }141+142+private function checkCategoryId(Activity $activity, SearchFilter $filter): ?bool143+ {144+$categoryId = $activity->getCategory()?->getUuid();145+if ($categoryId === null) {146+return null;147+ }148+149+return $filter->getFilterValue() === $categoryId ? null : false;150+ }151+152+private function checkMinDuration(Activity $activity, SearchFilter $filter): ?bool153+ {154+return $activity->getDuration() >= (float) $filter->getFilterValue() ? null : false;155+ }156+157+private function checkMaxDuration(Activity $activity, SearchFilter $filter): ?bool158+ {159+return $activity->getDuration() <= (float) $filter->getFilterValue() ? null : false;160+ }161+162+private function checkNotLogged(Activity $activity, SearchFilter $filter): ?bool163+ {164+if (! $filter->getFilterValue()) {165+return null;166+ }167+168+$isLogged = $activity->getCrmProviderId() !== null;169+$isInternal = $activity->isInternal();170+171+return (! $isLogged || $isInternal) ? null : false;172+ }173+174+private function checkOnlyRecorded(Activity $activity, SearchFilter $filter): ?bool175+ {176+$filterValue = (int) $filter->getFilterValue();177+$hasRecording = $activity->recording_state !== Activity::RECORDING_OFF;178+179+return match ($filterValue) {180+1 => $hasRecording ? null : false, // Only recorded181+2 => ! $hasRecording ? null : false, // Only non-recorded182+default => null,183+ };184+ }185+186+private function checkStageId(Activity $activity, SearchFilter $filter): ?bool187+ {188+$stageId = $activity->getStage()?->getUuid();189+if ($stageId === null) {190+return null; // No stage, let ES handle191+ }192+193+return $filter->getFilterValue() === $stageId ? null : false;194+ }195+196+private function checkStartDate(Activity $activity, SearchFilter $filter): ?bool197+ {198+$startTime = $activity->getActualStartTime();199+if ($startTime === null) {200+return null;201+ }202+203+$filterDate = Carbon::parse($filter->getFilterValue());204+205+return $startTime->gte($filterDate) ? null : false;206+ }207+208+private function checkEndDate(Activity $activity, SearchFilter $filter): ?bool209+ {210+$endTime = $activity->getActualEndTime();211+if ($endTime === null) {212+return null;213+ }214+215+$filterDate = Carbon::parse($filter->getFilterValue())->endOfDay();216+217+return $endTime->lte($filterDate) ? null : false;218+ }219+220+private function checkLanguages(Activity $activity, SearchFilter $filter): ?bool221+ {222+$activityLanguage = $activity->getLanguageCode();223+if ($activityLanguage === null) {224+return null;225+ }226+227+// Filter values are always base language codes (e.g., 'en', 'fr').228+// Extract base code from activity locale (e.g., en_GB -> en) to match ES query behavior.229+// See LanguageFilterDefinition::getQueries() which uses regex: $language . '_[a-z]{2}'230+$activityLangCode = explode('_', $activityLanguage)[0];231+$filterLanguage = $filter->getFilterValue();232+233+return $activityLangCode === $filterLanguage ? null : false;69 }234 }70}235}</selection>” selected.
Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
Expand
Listen
Gemini said
Gemini said
This code selection introduces a
pre-filtering mechanism
to the
Jiminny\Component\Nudge\Job
namespace. The primary goal is to optimize performance by validating an activity against search criteria in-memory before dispatching costly background jobs.
Core Functionality Changes
Core Functionality Changes
Selective Loading:
The
handle()
method now eager-loads
user.group
for activities and specifically filters for
FREQ_INSTANTLY
nudges and their associated search filters.
Pre-Dispatch Validation:
Instead of dispatching jobs for every instant nudge, the system now calls
activityMightMatchSearch()
.
Short-Circuiting:
If an activity fails a pre-filter check (e.g., mismatched user ID or duration), the job dispatch is skipped, and the event is logged with the specific mismatch reason.
Performance Metrics:
Adds summary logging at the end of the process to track:
Total searches processed.
Number of skipped dispatches.
The "Skip Rate" percentage.
Implemented Filter Checks
Implemented Filter Checks
The logic includes a
match
expression to validate various activity attributes against
SearchFilter
values:
Identity & Metadata:
Matches for
group_id
,
user_id
,
channel_id
, and
provider_id
.
Temporal & Duration:
* Validates
min_duration
and
max_duration
.
Checks
start_date
and
end_date
using Carbon parsing.
Activity State:
*
Logging:
Determines if an activity is logged to a CRM or is internal via
checkNotLogged
.
Recording:
Uses
checkOnlyRecorded
to filter based on whether a recording exists.
Categorization:
Checks for
category_id
,
stage_id
, and
languages
.
Note:
The language check specifically extracts base codes (e.g.,
en
from
en_GB
) to align with Elasticsearch behavior.
Logic Design
Logic Design
Nullable Returns:
Filter methods return
null
if a match is possible (or cannot be determined), and
false
only when a definitive mismatch is found.
Safe Fallback:
If a filter type is unknown (
default
), the system assumes a match and proceeds to dispatch, ensuring no false negatives.
Good response
Bad response
Share & export
Copy
Show more options
Copy prompt
You said what is the logic behind diff. Act as code reviewer. First review the changes then explain it and then evaluate. Try to find potential issues and bottlenecks
You said
what is the logic behind diff. Act as code reviewer. First review the changes then explain it and then evaluate. Try to find potential issues and bottlenecks
Expand
Listen
Show more options
Show thinking
Gemini said
Gemini said
Here is a review of the changes provided in the diff, broken down by your requested structure.
1. Review of Changes
1. Review of Changes
This PR refactors the
ProcessNudgeSearchJob
dispatching mechanism within the
handle()
method.
Query Optimization:
Eager loads necessary relationships (
user.group
,
filters
) and scopes the
nudges
relationship at the database level to only fetch
FREQ_INSTANTLY
records.
In-Memory Filtering:
Introduces a pre-filtering mechanism (
activityMightMatchSearch
) that checks the
Activity
against
SearchFilter
criteria before deciding to dispatch a job.
Helper Methods:
Adds 13 private
check*
methods to handle the specific comparison logic for different filter types (e.g., duration, dates, categories, stages).
Observability:
Adds structured logging to record exactly why a nudge was skipped and outputs a summary report (total, skipped, dispatched, skip rate) at the end of the execution.
2. Explanation of Logic
2. Explanation of Logic
The core philosophy of this change is
"veto-based short-circuiting"
.
Previously, the job fetched all searches with instant nudges for a team's users and blindly dispatched a queue job for every single one. The heavy lifting of deciding if the activity actually matched the search was likely deferred to the queue worker and Elasticsearch.
Now, the code evaluates the filters in the current process:
It iterates through each
Search
and its associated
SearchFilter
s.
It routes the filter to a specific
check*
method using a
match
expression based on the filter's property name.
The Veto:
The
check*
methods are designed to return
false
only if there is an absolute mismatch
(e.g., the filter requires a minimum duration of 10, but the activity is 5).
The Pass:
If the filter matches, or if the activity lacks the data needed to make a firm decision (e.g., no stage is assigned, or the filter type is unrecognized), the method returns
null
. This acts as a pass, delegating the final strict evaluation to Elasticsearch later in the pipeline.
If any filter returns
false
, the search is skipped, saving a queue dispatch.
3. Evaluation
3. Evaluation
Overall, this is a
highly effective performance optimization
.
Pros:
It significantly reduces queue bloat. By filtering out obvious mismatches in-memory, you save the overhead of serializing, dispatching, picking up, and processing jobs that are destined to fail or do nothing. The use of
match
makes the routing exceptionally clean, and the nullable return design is a smart way to avoid false negatives.
Cons/Trade-offs:
You are trading background queue worker time for a slight increase in synchronous memory and CPU usage on the current job. However, queue I/O is almost always more expensive than simple in-memory comparisons, making this a worthwhile trade.
4. Potential Issues & Bottlenecks
4. Potential Issues & Bottlenecks
While the logic is sound, there are a few architectural bottlenecks and risks introduced or maintained in this diff:
Potential N+1 Query / Lazy Loading Issues:
In the
handle
method, the activity is loaded with
Activity::with(['user.group'])
. However, inside your new
check*
methods, you are calling:
$activity->getCategory()?->getUuid()
$activity->getStage()?->getUuid()
If
category
and
stage
are Eloquent relationships and are not eager-loaded on the original
$activity
model, calling these methods inside a loop of
$totalSearches
will trigger lazy-loaded database queries.
Fix:
Update line 38 to:
$activity = Activity::with(['user.group', 'category', 'stage'])->...
Massive Memory Consumption (Pre-existing but critical):
Lines 39-41:
PHP
Download code
Copy code
$team
= Team::with([
'users'
])->findOrFail(
$activity
->user->team_id);
$usersIds
=
$team
->users->pluck(
'id'
)->toArray();
If a team has thousands of users,
Team::with(['users'])
hydrates thousands of full Eloquent User models into memory just to extract their IDs.
Fix:
Bypass hydrating the models entirely by querying the relationship directly:
$usersIds = $team->users()->pluck('id')->toArray();
Repeated Carbon Parsing in Loops:
In
checkStartDate
and
checkEndDate
, you parse the filter date:
Carbon::parse($filter->getFilterValue())
. If the same date filter applies to multiple searches, Carbon is being instantiated repeatedly in the loop. While Carbon is relatively fast, doing this hundreds of times adds unnecessary CPU cycles.
Fix:
This is a minor nitpick, but if performance is the absolute goal, you could memoize/cache the parsed filter values within the job.
Loose Type Comparisons:
In methods like
checkChannelId
or
checkLanguages
, you are using strict equality (
===
). Ensure that
$filter->getFilterValue()
(which is typically returned as a string from a database payload) matches the exact type returned by
$activity->getType()
or
$activityLangCode
. If one is an integer
1
and the other is a string
"1"
, the strict check will return
false
, incorrectly preventing the nudge from sending.
Good response
Bad response
Share & export
Copy
Show more options
Copy prompt
Edit
You said what would be your suggestion?
You said
what would be your suggestion?
Listen
Show more options
Show thinking
Gemini said
Gemini said
Here are actionable suggestions to address the potential issues and bottlenecks identified in the review. These optimizations focus on reducing memory footprint, preventing lazy-loading, and ensuring data type resilience.
1. Fix the N+1 Query Risk (Eager Loading)
1. Fix the N+1 Query Risk (Eager Loading)
Your
checkCategoryId
and
checkStageId
methods call
$activity->getCategory()
and
$activity->getStage()
. If these relationships aren't eager-loaded, Laravel will execute a new database query for every check inside the loop.
Suggestion:
Add
category
and
stage
to the initial eager-load array.
PHP...
|
[{"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":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":"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":"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":"Illuminate\\Queue\\MaxAttemptsExceededException: Jiminny\\Jobs\\Activity\\DeleteTeamChurnData has been attempted too many times. — 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":"Illuminate\\Queue\\MaxAttemptsExceededException: Jiminny\\Jobs\\Activity\\DeleteTeamChurnData has been attempted too many times. — jiminny — app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20818 move ask jiminny reports to its own datadog metric by LakyLak · Pull Request #12056 · 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-20818 move ask jiminny reports to its own datadog metric by LakyLak · Pull Request #12056 · 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":"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":false},{"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":"AXRadioButton","text":"Problem loading page","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Problem loading page","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Search the CRM - HubSpot docs","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search the CRM - HubSpot docs","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":"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":"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":"Dashboards | Datadog","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Dashboards | Datadog","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"AI Features | Datadog","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"AI Features | Datadog","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 20493 smart instant nudge pre filtering by nikolaybiaivanov · Pull Request #12053 · 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 20493 smart instant nudge pre filtering by nikolaybiaivanov · Pull Request #12053 · 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.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":"Close 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.0034722222,"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.02673611,"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.05,"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":"AXButton","text":"AI Chat settings","depth":7,"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":"Close","depth":7,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","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":"AXButton","text":"Main menu","depth":12,"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","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":"AXHeading","text":"Conversation with Gemini","depth":15,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said I’m on page “<tabTitle>Jy 20493 smart instant nudge pre filtering by niko</tabTitle>” with “<selection>@@ -4,16 +4,17 @@445namespace Jiminny\\Component\\Nudge\\Job;5namespace Jiminny\\Component\\Nudge\\Job;667+use Carbon\\Carbon;7use Illuminate\\Bus\\Queueable;8use Illuminate\\Bus\\Queueable;8use Illuminate\\Contracts\\Queue\\ShouldQueue;9use Illuminate\\Contracts\\Queue\\ShouldQueue;9-use Illuminate\\Database\\Eloquent\\Builder;10use Illuminate\\Foundation\\Bus\\Dispatchable;10use Illuminate\\Foundation\\Bus\\Dispatchable;11use Illuminate\\Queue\\InteractsWithQueue;11use Illuminate\\Queue\\InteractsWithQueue;12use Illuminate\\Queue\\SerializesModels;12use Illuminate\\Queue\\SerializesModels;13use Illuminate\\Support\\Facades\\Log;13use Illuminate\\Support\\Facades\\Log;14use Jiminny\\Component\\Queue\\Constants;14use Jiminny\\Component\\Queue\\Constants;15use Jiminny\\Models\\Activity;15use Jiminny\\Models\\Activity;16use Jiminny\\Models\\Activity\\Search;16use Jiminny\\Models\\Activity\\Search;17+use Jiminny\\Models\\Activity\\SearchFilter;17use Jiminny\\Models\\Nudge;18use Jiminny\\Models\\Nudge;18use Jiminny\\Models\\Team;19use Jiminny\\Models\\Team;1920@@ -34,37 +35,201 @@343535public function handle(): void36public function handle(): void36 {37 {37-/** @var Activity $activity */38+$activity = Activity::with(['user.group'])->uuid($this->activityUuid, false)->firstOrFail();38-$activity = Activity::with(['user'])->uuid($this->activityUuid, false)->firstOrFail();39-40-/** @var Team $team */41$team = Team::with(['users'])->findOrFail($activity->user->team_id);39$team = Team::with(['users'])->findOrFail($activity->user->team_id);424043- Log::info(__METHOD__ . " Running for team $team->id.", [44-'activity_id' => $activity->id,45-'activity_uuid' => $this->activityUuid,46-'team_id' => $team->id,47- ]);48-49$usersIds = $team->users->pluck('id')->toArray();41$usersIds = $team->users->pluck('id')->toArray();504251-$searchesWithImmediateNudges = Activity\\Search::with(['nudges'])43+$searchesWithImmediateNudges = Activity\\Search::with([44+'nudges' => fn ($q) => $q->where('frequency', Nudge::FREQ_INSTANTLY),45+'filters',46+ ])52 ->whereIn('user_id', $usersIds)47 ->whereIn('user_id', $usersIds)53- ->whereHas('nudges', function (Builder $query) {48+ ->whereHas('nudges', fn ($q) => $q->where('frequency', Nudge::FREQ_INSTANTLY))54-$query->where('frequency', Nudge::FREQ_INSTANTLY);49+ ->get();55- })->get();50+51+$totalSearches = $searchesWithImmediateNudges->count();52+$skippedCount = 0;53+54+$searchesWithImmediateNudges->each(function (Search $search) use ($activity, &$skippedCount): void {55+$matchResult = $this->activityMightMatchSearch($activity, $search);565657-$searchesWithImmediateNudges->each(function (Search $search): void {57+if (! $matchResult['matches']) {58-$search->nudges->each(function (Nudge $nudge): void {58+$skippedCount++;59-// Filter only nudges that are set to be sent instantly59+ Log::info('Pre-filter skipped nudge dispatch', [60-if ($nudge->frequency === Nudge::FREQ_INSTANTLY) {60+'activity_uuid' => $activity->getUuid(),61- Log::info("Dispatching ProcessNudgeSearchJob for nudge $nudge->id.");61+'search_id' => $search->getId(),62+'mismatched_filter' => $matchResult['mismatch_reason'],63+'filter_value' => $matchResult['filter_value'],64+ ]);626563- ProcessNudgeSearchJob::dispatch($nudge);66+return;67+ }646865- Log::info("ProcessNudgeSearchJob dispatched for nudge $nudge->id.");69+$search->nudges->each(fn ($nudge) => ProcessNudgeSearchJob::dispatch($nudge));66- }67- });68 });70 });71+72+if ($totalSearches > 0) {73+ Log::info('Nudge pre-filter results', [74+'activity_uuid' => $activity->getUuid(),75+'total_searches' => $totalSearches,76+'skipped' => $skippedCount,77+'dispatched' => $totalSearches - $skippedCount,78+'skip_rate' => round(($skippedCount / $totalSearches) * 100, 2) . '%',79+ ]);80+ }81+ }82+83+private function activityMightMatchSearch(Activity $activity, Search $search): array84+ {85+foreach ($search->filters as $filter) {86+$filterName = $filter->getFilterProperty();87+88+$result = match ($filterName) {89+'group_id' => $this->checkGroupId($activity, $filter),90+'user_id' => $this->checkUserId($activity, $filter),91+'channel_id' => $this->checkChannelId($activity, $filter),92+'provider_id' => $this->checkProviderId($activity, $filter),93+'category_id' => $this->checkCategoryId($activity, $filter),94+'min_duration' => $this->checkMinDuration($activity, $filter),95+'max_duration' => $this->checkMaxDuration($activity, $filter),96+'not_logged' => $this->checkNotLogged($activity, $filter),97+'only_recorded' => $this->checkOnlyRecorded($activity, $filter),98+'languages' => $this->checkLanguages($activity, $filter),99+'stage_id' => $this->checkStageId($activity, $filter),100+'start_date' => $this->checkStartDate($activity, $filter),101+'end_date' => $this->checkEndDate($activity, $filter),102+default => null, // Unknown filter - can't pre-check, assume might match103+ };104+105+if ($result === false) {106+return [107+'matches' => false,108+'mismatch_reason' => $filterName,109+'filter_value' => $filter->getFilterValue(),110+ ];111+ }112+ }113+114+return ['matches' => true];115+ }116+117+private function checkGroupId(Activity $activity, SearchFilter $filter): ?bool118+ {119+$groupUuid = $activity->user->getGroup()?->getUuid();120+if ($groupUuid === null) {121+return null;122+ }123+124+return $filter->getFilterValue() === $groupUuid ? null : false;125+ }126+127+private function checkUserId(Activity $activity, SearchFilter $filter): ?bool128+ {129+return $filter->getFilterValue() === $activity->user->getUuid() ? null : false;130+ }131+132+private function checkChannelId(Activity $activity, SearchFilter $filter): ?bool133+ {134+return $filter->getFilterValue() === $activity->getType() ? null : false;135+ }136+137+private function checkProviderId(Activity $activity, SearchFilter $filter): ?bool138+ {139+return $filter->getFilterValue() === $activity->getProvider() ? null : false;140+ }141+142+private function checkCategoryId(Activity $activity, SearchFilter $filter): ?bool143+ {144+$categoryId = $activity->getCategory()?->getUuid();145+if ($categoryId === null) {146+return null;147+ }148+149+return $filter->getFilterValue() === $categoryId ? null : false;150+ }151+152+private function checkMinDuration(Activity $activity, SearchFilter $filter): ?bool153+ {154+return $activity->getDuration() >= (float) $filter->getFilterValue() ? null : false;155+ }156+157+private function checkMaxDuration(Activity $activity, SearchFilter $filter): ?bool158+ {159+return $activity->getDuration() <= (float) $filter->getFilterValue() ? null : false;160+ }161+162+private function checkNotLogged(Activity $activity, SearchFilter $filter): ?bool163+ {164+if (! $filter->getFilterValue()) {165+return null;166+ }167+168+$isLogged = $activity->getCrmProviderId() !== null;169+$isInternal = $activity->isInternal();170+171+return (! $isLogged || $isInternal) ? null : false;172+ }173+174+private function checkOnlyRecorded(Activity $activity, SearchFilter $filter): ?bool175+ {176+$filterValue = (int) $filter->getFilterValue();177+$hasRecording = $activity->recording_state !== Activity::RECORDING_OFF;178+179+return match ($filterValue) {180+1 => $hasRecording ? null : false, // Only recorded181+2 => ! $hasRecording ? null : false, // Only non-recorded182+default => null,183+ };184+ }185+186+private function checkStageId(Activity $activity, SearchFilter $filter): ?bool187+ {188+$stageId = $activity->getStage()?->getUuid();189+if ($stageId === null) {190+return null; // No stage, let ES handle191+ }192+193+return $filter->getFilterValue() === $stageId ? null : false;194+ }195+196+private function checkStartDate(Activity $activity, SearchFilter $filter): ?bool197+ {198+$startTime = $activity->getActualStartTime();199+if ($startTime === null) {200+return null;201+ }202+203+$filterDate = Carbon::parse($filter->getFilterValue());204+205+return $startTime->gte($filterDate) ? null : false;206+ }207+208+private function checkEndDate(Activity $activity, SearchFilter $filter): ?bool209+ {210+$endTime = $activity->getActualEndTime();211+if ($endTime === null) {212+return null;213+ }214+215+$filterDate = Carbon::parse($filter->getFilterValue())->endOfDay();216+217+return $endTime->lte($filterDate) ? null : false;218+ }219+220+private function checkLanguages(Activity $activity, SearchFilter $filter): ?bool221+ {222+$activityLanguage = $activity->getLanguageCode();223+if ($activityLanguage === null) {224+return null;225+ }226+227+// Filter values are always base language codes (e.g., 'en', 'fr').228+// Extract base code from activity locale (e.g., en_GB -> en) to match ES query behavior.229+// See LanguageFilterDefinition::getQueries() which uses regex: $language . '_[a-z]{2}'230+$activityLangCode = explode('_', $activityLanguage)[0];231+$filterLanguage = $filter->getFilterValue();232+233+return $activityLangCode === $filterLanguage ? null : false;69 }234 }70}235}</selection>” selected. Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.","depth":21,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"I’m on page “<tabTitle>Jy 20493 smart instant nudge pre filtering by niko</tabTitle>” with “<selection>@@ -4,16 +4,17 @@445namespace Jiminny\\Component\\Nudge\\Job;5namespace Jiminny\\Component\\Nudge\\Job;667+use Carbon\\Carbon;7use Illuminate\\Bus\\Queueable;8use Illuminate\\Bus\\Queueable;8use Illuminate\\Contracts\\Queue\\ShouldQueue;9use Illuminate\\Contracts\\Queue\\ShouldQueue;9-use Illuminate\\Database\\Eloquent\\Builder;10use Illuminate\\Foundation\\Bus\\Dispatchable;10use Illuminate\\Foundation\\Bus\\Dispatchable;11use Illuminate\\Queue\\InteractsWithQueue;11use Illuminate\\Queue\\InteractsWithQueue;12use Illuminate\\Queue\\SerializesModels;12use Illuminate\\Queue\\SerializesModels;13use Illuminate\\Support\\Facades\\Log;13use Illuminate\\Support\\Facades\\Log;14use Jiminny\\Component\\Queue\\Constants;14use Jiminny\\Component\\Queue\\Constants;15use Jiminny\\Models\\Activity;15use Jiminny\\Models\\Activity;16use Jiminny\\Models\\Activity\\Search;16use Jiminny\\Models\\Activity\\Search;17+use Jiminny\\Models\\Activity\\SearchFilter;17use Jiminny\\Models\\Nudge;18use Jiminny\\Models\\Nudge;18use Jiminny\\Models\\Team;19use Jiminny\\Models\\Team;1920@@ -34,37 +35,201 @@343535public function handle(): void36public function handle(): void36 {37 {37-/** @var Activity $activity */38+$activity = Activity::with(['user.group'])->uuid($this->activityUuid, false)->firstOrFail();38-$activity = Activity::with(['user'])->uuid($this->activityUuid, false)->firstOrFail();39-40-/** @var Team $team */41$team = Team::with(['users'])->findOrFail($activity->user->team_id);39$team = Team::with(['users'])->findOrFail($activity->user->team_id);424043- Log::info(__METHOD__ . " Running for team $team->id.", [44-'activity_id' => $activity->id,45-'activity_uuid' => $this->activityUuid,46-'team_id' => $team->id,47- ]);48-49$usersIds = $team->users->pluck('id')->toArray();41$usersIds = $team->users->pluck('id')->toArray();504251-$searchesWithImmediateNudges = Activity\\Search::with(['nudges'])43+$searchesWithImmediateNudges = Activity\\Search::with([44+'nudges' => fn ($q) => $q->where('frequency', Nudge::FREQ_INSTANTLY),45+'filters',46+ ])52 ->whereIn('user_id', $usersIds)47 ->whereIn('user_id', $usersIds)53- ->whereHas('nudges', function (Builder $query) {48+ ->whereHas('nudges', fn ($q) => $q->where('frequency', Nudge::FREQ_INSTANTLY))54-$query->where('frequency', Nudge::FREQ_INSTANTLY);49+ ->get();55- })->get();50+51+$totalSearches = $searchesWithImmediateNudges->count();52+$skippedCount = 0;53+54+$searchesWithImmediateNudges->each(function (Search $search) use ($activity, &$skippedCount): void {55+$matchResult = $this->activityMightMatchSearch($activity, $search);565657-$searchesWithImmediateNudges->each(function (Search $search): void {57+if (! $matchResult['matches']) {58-$search->nudges->each(function (Nudge $nudge): void {58+$skippedCount++;59-// Filter only nudges that are set to be sent instantly59+ Log::info('Pre-filter skipped nudge dispatch', [60-if ($nudge->frequency === Nudge::FREQ_INSTANTLY) {60+'activity_uuid' => $activity->getUuid(),61- Log::info("Dispatching ProcessNudgeSearchJob for nudge $nudge->id.");61+'search_id' => $search->getId(),62+'mismatched_filter' => $matchResult['mismatch_reason'],63+'filter_value' => $matchResult['filter_value'],64+ ]);626563- ProcessNudgeSearchJob::dispatch($nudge);66+return;67+ }646865- Log::info("ProcessNudgeSearchJob dispatched for nudge $nudge->id.");69+$search->nudges->each(fn ($nudge) => ProcessNudgeSearchJob::dispatch($nudge));66- }67- });68 });70 });71+72+if ($totalSearches > 0) {73+ Log::info('Nudge pre-filter results', [74+'activity_uuid' => $activity->getUuid(),75+'total_searches' => $totalSearches,76+'skipped' => $skippedCount,77+'dispatched' => $totalSearches - $skippedCount,78+'skip_rate' => round(($skippedCount / $totalSearches) * 100, 2) . '%',79+ ]);80+ }81+ }82+83+private function activityMightMatchSearch(Activity $activity, Search $search): array84+ {85+foreach ($search->filters as $filter) {86+$filterName = $filter->getFilterProperty();87+88+$result = match ($filterName) {89+'group_id' => $this->checkGroupId($activity, $filter),90+'user_id' => $this->checkUserId($activity, $filter),91+'channel_id' => $this->checkChannelId($activity, $filter),92+'provider_id' => $this->checkProviderId($activity, $filter),93+'category_id' => $this->checkCategoryId($activity, $filter),94+'min_duration' => $this->checkMinDuration($activity, $filter),95+'max_duration' => $this->checkMaxDuration($activity, $filter),96+'not_logged' => $this->checkNotLogged($activity, $filter),97+'only_recorded' => $this->checkOnlyRecorded($activity, $filter),98+'languages' => $this->checkLanguages($activity, $filter),99+'stage_id' => $this->checkStageId($activity, $filter),100+'start_date' => $this->checkStartDate($activity, $filter),101+'end_date' => $this->checkEndDate($activity, $filter),102+default => null, // Unknown filter - can't pre-check, assume might match103+ };104+105+if ($result === false) {106+return [107+'matches' => false,108+'mismatch_reason' => $filterName,109+'filter_value' => $filter->getFilterValue(),110+ ];111+ }112+ }113+114+return ['matches' => true];115+ }116+117+private function checkGroupId(Activity $activity, SearchFilter $filter): ?bool118+ {119+$groupUuid = $activity->user->getGroup()?->getUuid();120+if ($groupUuid === null) {121+return null;122+ }123+124+return $filter->getFilterValue() === $groupUuid ? null : false;125+ }126+127+private function checkUserId(Activity $activity, SearchFilter $filter): ?bool128+ {129+return $filter->getFilterValue() === $activity->user->getUuid() ? null : false;130+ }131+132+private function checkChannelId(Activity $activity, SearchFilter $filter): ?bool133+ {134+return $filter->getFilterValue() === $activity->getType() ? null : false;135+ }136+137+private function checkProviderId(Activity $activity, SearchFilter $filter): ?bool138+ {139+return $filter->getFilterValue() === $activity->getProvider() ? null : false;140+ }141+142+private function checkCategoryId(Activity $activity, SearchFilter $filter): ?bool143+ {144+$categoryId = $activity->getCategory()?->getUuid();145+if ($categoryId === null) {146+return null;147+ }148+149+return $filter->getFilterValue() === $categoryId ? null : false;150+ }151+152+private function checkMinDuration(Activity $activity, SearchFilter $filter): ?bool153+ {154+return $activity->getDuration() >= (float) $filter->getFilterValue() ? null : false;155+ }156+157+private function checkMaxDuration(Activity $activity, SearchFilter $filter): ?bool158+ {159+return $activity->getDuration() <= (float) $filter->getFilterValue() ? null : false;160+ }161+162+private function checkNotLogged(Activity $activity, SearchFilter $filter): ?bool163+ {164+if (! $filter->getFilterValue()) {165+return null;166+ }167+168+$isLogged = $activity->getCrmProviderId() !== null;169+$isInternal = $activity->isInternal();170+171+return (! $isLogged || $isInternal) ? null : false;172+ }173+174+private function checkOnlyRecorded(Activity $activity, SearchFilter $filter): ?bool175+ {176+$filterValue = (int) $filter->getFilterValue();177+$hasRecording = $activity->recording_state !== Activity::RECORDING_OFF;178+179+return match ($filterValue) {180+1 => $hasRecording ? null : false, // Only recorded181+2 => ! $hasRecording ? null : false, // Only non-recorded182+default => null,183+ };184+ }185+186+private function checkStageId(Activity $activity, SearchFilter $filter): ?bool187+ {188+$stageId = $activity->getStage()?->getUuid();189+if ($stageId === null) {190+return null; // No stage, let ES handle191+ }192+193+return $filter->getFilterValue() === $stageId ? null : false;194+ }195+196+private function checkStartDate(Activity $activity, SearchFilter $filter): ?bool197+ {198+$startTime = $activity->getActualStartTime();199+if ($startTime === null) {200+return null;201+ }202+203+$filterDate = Carbon::parse($filter->getFilterValue());204+205+return $startTime->gte($filterDate) ? null : false;206+ }207+208+private function checkEndDate(Activity $activity, SearchFilter $filter): ?bool209+ {210+$endTime = $activity->getActualEndTime();211+if ($endTime === null) {212+return null;213+ }214+215+$filterDate = Carbon::parse($filter->getFilterValue())->endOfDay();216+217+return $endTime->lte($filterDate) ? null : false;218+ }219+220+private function checkLanguages(Activity $activity, SearchFilter $filter): ?bool221+ {222+$activityLanguage = $activity->getLanguageCode();223+if ($activityLanguage === null) {224+return null;225+ }226+227+// Filter values are always base language codes (e.g., 'en', 'fr').228+// Extract base code from activity locale (e.g., en_GB -> en) to match ES query behavior.229+// See LanguageFilterDefinition::getQueries() which uses regex: $language . '_[a-z]{2}'230+$activityLangCode = explode('_', $activityLanguage)[0];231+$filterLanguage = $filter->getFilterValue();232+233+return $activityLangCode === $filterLanguage ? null : false;69 }234 }70}235}</selection>” selected.","depth":23,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.","depth":23,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Expand","depth":21,"on_screen":false,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Listen","depth":22,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Gemini said","depth":20,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"This code selection introduces a","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"pre-filtering mechanism","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to the","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Component\\Nudge\\Job","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"namespace. The primary goal is to optimize performance by validating an activity against search criteria in-memory before dispatching costly background jobs.","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Core Functionality Changes","depth":23,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Core Functionality Changes","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Selective Loading:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"handle()","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"method now eager-loads","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"user.group","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"for activities and specifically filters for","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FREQ_INSTANTLY","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"nudges and their associated search filters.","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pre-Dispatch Validation:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Instead of dispatching jobs for every instant nudge, the system now calls","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"activityMightMatchSearch()","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Short-Circuiting:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If an activity fails a pre-filter check (e.g., mismatched user ID or duration), the job dispatch is skipped, and the event is logged with the specific mismatch reason.","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Performance Metrics:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Adds summary logging at the end of the process to track:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Total searches processed.","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Number of skipped dispatches.","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The \"Skip Rate\" percentage.","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Implemented Filter Checks","depth":23,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Implemented Filter Checks","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The logic includes a","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"match","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"expression to validate various activity attributes against","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SearchFilter","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"values:","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Identity & Metadata:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Matches for","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"group_id","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"user_id","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"channel_id","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", and","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"provider_id","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Temporal & Duration:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"* Validates","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"min_duration","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"max_duration","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Checks","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"start_date","depth":29,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"end_date","depth":29,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"using Carbon parsing.","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Activity State:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Logging:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Determines if an activity is logged to a CRM or is internal via","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"checkNotLogged","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Recording:","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Uses","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"checkOnlyRecorded","depth":29,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to filter based on whether a recording exists.","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Categorization:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Checks for","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"category_id","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"stage_id","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", and","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"languages","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Note:","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The language check specifically extracts base codes (e.g.,","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"en","depth":29,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"from","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"en_GB","depth":29,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") to align with Elasticsearch behavior.","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Logic Design","depth":23,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Logic Design","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nullable Returns:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Filter methods return","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"null","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"if a match is possible (or cannot be determined), and","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"false","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"only when a definitive mismatch is found.","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Safe Fallback:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If a filter type is unknown (","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"default","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"), the system assumes a match and proceeds to dispatch, ensuring no false negatives.","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Good response","depth":22,"on_screen":false,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bad response","depth":22,"on_screen":false,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Share & export","depth":21,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Copy","depth":22,"on_screen":false,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":21,"on_screen":false,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Copy prompt","depth":21,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said what is the logic behind diff. Act as code reviewer. First review the changes then explain it and then evaluate. Try to find potential issues and bottlenecks","depth":21,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"what is the logic behind diff. Act as code reviewer. First review the changes then explain it and then evaluate. Try to find potential issues and bottlenecks","depth":23,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Expand","depth":21,"on_screen":false,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Listen","depth":22,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"on_screen":false,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Here is a review of the changes provided in the diff, broken down by your requested structure.","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. Review of Changes","depth":23,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. Review of Changes","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"This PR refactors the","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ProcessNudgeSearchJob","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dispatching mechanism within the","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"handle()","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"method.","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Query Optimization:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Eager loads necessary relationships (","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"user.group","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"filters","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") and scopes the","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"nudges","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"relationship at the database level to only fetch","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FREQ_INSTANTLY","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"records.","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"In-Memory Filtering:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Introduces a pre-filtering mechanism (","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"activityMightMatchSearch","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") that checks the","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Activity","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"against","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SearchFilter","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"criteria before deciding to dispatch a job.","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Helper Methods:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Adds 13 private","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"check*","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"methods to handle the specific comparison logic for different filter types (e.g., duration, dates, categories, stages).","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Observability:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Adds structured logging to record exactly why a nudge was skipped and outputs a summary report (total, skipped, dispatched, skip rate) at the end of the execution.","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. Explanation of Logic","depth":23,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. Explanation of Logic","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The core philosophy of this change is","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"veto-based short-circuiting\"","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Previously, the job fetched all searches with instant nudges for a team's users and blindly dispatched a queue job for every single one. The heavy lifting of deciding if the activity actually matched the search was likely deferred to the queue worker and Elasticsearch.","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Now, the code evaluates the filters in the current process:","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"It iterates through each","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and its associated","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SearchFilter","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"s.","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"It routes the filter to a specific","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"check*","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"method using a","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"match","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"expression based on the filter's property name.","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Veto:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"check*","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"methods are designed to return","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"false","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"only if there is an absolute mismatch","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(e.g., the filter requires a minimum duration of 10, but the activity is 5).","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Pass:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If the filter matches, or if the activity lacks the data needed to make a firm decision (e.g., no stage is assigned, or the filter type is unrecognized), the method returns","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"null","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":". This acts as a pass, delegating the final strict evaluation to Elasticsearch later in the pipeline.","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If any filter returns","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"false","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", the search is skipped, saving a queue dispatch.","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"3. Evaluation","depth":23,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3. Evaluation","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Overall, this is a","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"highly effective performance optimization","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pros:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"It significantly reduces queue bloat. By filtering out obvious mismatches in-memory, you save the overhead of serializing, dispatching, picking up, and processing jobs that are destined to fail or do nothing. The use of","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"match","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"makes the routing exceptionally clean, and the nullable return design is a smart way to avoid false negatives.","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Cons/Trade-offs:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You are trading background queue worker time for a slight increase in synchronous memory and CPU usage on the current job. However, queue I/O is almost always more expensive than simple in-memory comparisons, making this a worthwhile trade.","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"4. Potential Issues & Bottlenecks","depth":23,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4. Potential Issues & Bottlenecks","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"While the logic is sound, there are a few architectural bottlenecks and risks introduced or maintained in this diff:","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Potential N+1 Query / Lazy Loading Issues:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"In the","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"handle","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"method, the activity is loaded with","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Activity::with(['user.group'])","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":". However, inside your new","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"check*","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"methods, you are calling:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$activity->getCategory()?->getUuid()","depth":29,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$activity->getStage()?->getUuid()","depth":29,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"category","depth":29,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"stage","depth":29,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"are Eloquent relationships and are not eager-loaded on the original","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$activity","depth":29,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"model, calling these methods inside a loop of","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$totalSearches","depth":29,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"will trigger lazy-loaded database queries.","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fix:","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Update line 38 to:","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$activity = Activity::with(['user.group', 'category', 'stage'])->...","depth":29,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Massive Memory Consumption (Pre-existing but critical):","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Lines 39-41:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PHP","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Download code","depth":27,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Copy code","depth":27,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"$team","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"= Team::with([","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'users'","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"])->findOrFail(","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$activity","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->user->team_id);","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$usersIds","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$team","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->users->pluck(","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'id'","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")->toArray();","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If a team has thousands of users,","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Team::with(['users'])","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"hydrates thousands of full Eloquent User models into memory just to extract their IDs.","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fix:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Bypass hydrating the models entirely by querying the relationship directly:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$usersIds = $team->users()->pluck('id')->toArray();","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repeated Carbon Parsing in Loops:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"In","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"checkStartDate","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"checkEndDate","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", you parse the filter date:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Carbon::parse($filter->getFilterValue())","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":". If the same date filter applies to multiple searches, Carbon is being instantiated repeatedly in the loop. While Carbon is relatively fast, doing this hundreds of times adds unnecessary CPU cycles.","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fix:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"This is a minor nitpick, but if performance is the absolute goal, you could memoize/cache the parsed filter values within the job.","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Loose Type Comparisons:","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"In methods like","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"checkChannelId","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"or","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"checkLanguages","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", you are using strict equality (","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"===","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"). Ensure that","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$filter->getFilterValue()","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(which is typically returned as a string from a database payload) matches the exact type returned by","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$activity->getType()","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"or","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$activityLangCode","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":". If one is an integer","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and the other is a string","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"1\"","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", the strict check will return","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"false","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", incorrectly preventing the nudge from sending.","depth":26,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Good response","depth":22,"on_screen":false,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bad response","depth":22,"on_screen":false,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Share & export","depth":21,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Copy","depth":22,"on_screen":false,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":21,"on_screen":false,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Copy prompt","depth":21,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"on_screen":false,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said what would be your suggestion?","depth":21,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"what would be your suggestion?","depth":23,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":25,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Here are actionable suggestions to address the potential issues and bottlenecks identified in the review. These optimizations focus on reducing memory footprint, preventing lazy-loading, and ensuring data type resilience.","depth":24,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. Fix the N+1 Query Risk (Eager Loading)","depth":23,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. Fix the N+1 Query Risk (Eager Loading)","depth":24,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Your","depth":24,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"checkCategoryId","depth":25,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":24,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"checkStageId","depth":25,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"methods call","depth":24,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$activity->getCategory()","depth":25,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":24,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$activity->getStage()","depth":25,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":". If these relationships aren't eager-loaded, Laravel will execute a new database query for every check inside the loop.","depth":24,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Suggestion:","depth":24,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Add","depth":24,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"category","depth":25,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":24,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"stage","depth":25,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to the initial eager-load array.","depth":24,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PHP","depth":25,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8258156237367837636
|
6059963422155872515
|
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
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST [URL_WITH_CREDENTIALS] -4,16 +4,17 @@445namespace Jiminny\Component\Nudge\Job;5namespace Jiminny\Component\Nudge\Job;667+use Carbon\Carbon;7use Illuminate\Bus\Queueable;8use Illuminate\Bus\Queueable;8use Illuminate\Contracts\Queue\ShouldQueue;9use Illuminate\Contracts\Queue\ShouldQueue;9-use Illuminate\Database\Eloquent\Builder;10use Illuminate\Foundation\Bus\Dispatchable;10use Illuminate\Foundation\Bus\Dispatchable;11use Illuminate\Queue\InteractsWithQueue;11use Illuminate\Queue\InteractsWithQueue;12use Illuminate\Queue\SerializesModels;12use Illuminate\Queue\SerializesModels;13use Illuminate\Support\Facades\Log;13use Illuminate\Support\Facades\Log;14use Jiminny\Component\Queue\Constants;14use Jiminny\Component\Queue\Constants;15use Jiminny\Models\Activity;15use Jiminny\Models\Activity;16use Jiminny\Models\Activity\Search;16use Jiminny\Models\Activity\Search;17+use Jiminny\Models\Activity\SearchFilter;17use Jiminny\Models\Nudge;18use Jiminny\Models\Nudge;18use Jiminny\Models\Team;19use Jiminny\Models\Team;1920@@ -34,37 +35,201 @@343535public function handle(): void36public function handle(): void36 {37 {37-/** @var Activity $activity */38+$activity = Activity::with(['user.group'])->uuid($this->activityUuid, false)->firstOrFail();38-$activity = Activity::with(['user'])->uuid($this->activityUuid, false)->firstOrFail();39-40-/** @var Team $team */41$team = Team::with(['users'])->findOrFail($activity->user->team_id);39$team = Team::with(['users'])->findOrFail($activity->user->team_id);424043- Log::info(__METHOD__ . " Running for team $team->id.", [44-'activity_id' => $activity->id,45-'activity_uuid' => $this->activityUuid,46-'team_id' => $team->id,47- ]);48-49$usersIds = $team->users->pluck('id')->toArray();41$usersIds = $team->users->pluck('id')->toArray();504251-$searchesWithImmediateNudges = Activity\Search::with(['nudges'])43+$searchesWithImmediateNudges = Activity\Search::with([44+'nudges' => fn ($q) => $q->where('frequency', Nudge::FREQ_INSTANTLY),45+'filters',46+ ])52 ->whereIn('user_id', $usersIds)47 ->whereIn('user_id', $usersIds)53- ->whereHas('nudges', function (Builder $query) {48+ ->whereHas('nudges', fn ($q) => $q->where('frequency', Nudge::FREQ_INSTANTLY))54-$query->where('frequency', Nudge::FREQ_INSTANTLY);49+ ->get();55- })->get();50+51+$totalSearches = $searchesWithImmediateNudges->count();52+$skippedCount = 0;53+54+$searchesWithImmediateNudges->each(function (Search $search) use ($activity, &$skippedCount): void {55+$matchResult = $this->activityMightMatchSearch($activity, $search);565657-$searchesWithImmediateNudges->each(function (Search $search): void {57+if (! $matchResult['matches']) {58-$search->nudges->each(function (Nudge $nudge): void {58+$skippedCount++;59-// Filter only nudges that are set to be sent instantly59+ Log::info('Pre-filter skipped nudge dispatch', [60-if ($nudge->frequency === Nudge::FREQ_INSTANTLY) {60+'activity_uuid' => $activity->getUuid(),61- Log::info("Dispatching ProcessNudgeSearchJob for nudge $nudge->id.");61+'search_id' => $search->getId(),62+'mismatched_filter' => $matchResult['mismatch_reason'],63+'filter_value' => $matchResult['filter_value'],64+ ]);626563- ProcessNudgeSearchJob::dispatch($nudge);66+return;67+ }646865- Log::info("ProcessNudgeSearchJob dispatched for nudge $nudge->id.");69+$search->nudges->each(fn ($nudge) => ProcessNudgeSearchJob::dispatch($nudge));66- }67- });68 });70 });71+72+if ($totalSearches > 0) {73+ Log::info('Nudge pre-filter results', [74+'activity_uuid' => $activity->getUuid(),75+'total_searches' => $totalSearches,76+'skipped' => $skippedCount,77+'dispatched' => $totalSearches - $skippedCount,78+'skip_rate' => round(($skippedCount / $totalSearches) * 100, 2) . '%',79+ ]);80+ }81+ }82+83+private function activityMightMatchSearch(Activity $activity, Search $search): array84+ {85+foreach ($search->filters as $filter) {86+$filterName = $filter->getFilterProperty();87+88+$result = match ($filterName) {89+'group_id' => $this->checkGroupId($activity, $filter),90+'user_id' => $this->checkUserId($activity, $filter),91+'channel_id' => $this->checkChannelId($activity, $filter),92+'provider_id' => $this->checkProviderId($activity, $filter),93+'category_id' => $this->checkCategoryId($activity, $filter),94+'min_duration' => $this->checkMinDuration($activity, $filter),95+'max_duration' => $this->checkMaxDuration($activity, $filter),96+'not_logged' => $this->checkNotLogged($activity, $filter),97+'only_recorded' => $this->checkOnlyRecorded($activity, $filter),98+'languages' => $this->checkLanguages($activity, $filter),99+'stage_id' => $this->checkStageId($activity, $filter),100+'start_date' => $this->checkStartDate($activity, $filter),101+'end_date' => $this->checkEndDate($activity, $filter),102+default => null, // Unknown filter - can't pre-check, assume might match103+ };104+105+if ($result === false) {106+return [107+'matches' => false,108+'mismatch_reason' => $filterName,109+'filter_value' => $filter->getFilterValue(),110+ ];111+ }112+ }113+114+return ['matches' => true];115+ }116+117+private function checkGroupId(Activity $activity, SearchFilter $filter): ?bool118+ {119+$groupUuid = $activity->user->getGroup()?->getUuid();120+if ($groupUuid === null) {121+return null;122+ }123+124+return $filter->getFilterValue() === $groupUuid ? null : false;125+ }126+127+private function checkUserId(Activity $activity, SearchFilter $filter): ?bool128+ {129+return $filter->getFilterValue() === $activity->user->getUuid() ? null : false;130+ }131+132+private function checkChannelId(Activity $activity, SearchFilter $filter): ?bool133+ {134+return $filter->getFilterValue() === $activity->getType() ? null : false;135+ }136+137+private function checkProviderId(Activity $activity, SearchFilter $filter): ?bool138+ {139+return $filter->getFilterValue() === $activity->getProvider() ? null : false;140+ }141+142+private function checkCategoryId(Activity $activity, SearchFilter $filter): ?bool143+ {144+$categoryId = $activity->getCategory()?->getUuid();145+if ($categoryId === null) {146+return null;147+ }148+149+return $filter->getFilterValue() === $categoryId ? null : false;150+ }151+152+private function checkMinDuration(Activity $activity, SearchFilter $filter): ?bool153+ {154+return $activity->getDuration() >= (float) $filter->getFilterValue() ? null : false;155+ }156+157+private function checkMaxDuration(Activity $activity, SearchFilter $filter): ?bool158+ {159+return $activity->getDuration() <= (float) $filter->getFilterValue() ? null : false;160+ }161+162+private function checkNotLogged(Activity $activity, SearchFilter $filter): ?bool163+ {164+if (! $filter->getFilterValue()) {165+return null;166+ }167+168+$isLogged = $activity->getCrmProviderId() !== null;169+$isInternal = $activity->isInternal();170+171+return (! $isLogged || $isInternal) ? null : false;172+ }173+174+private function checkOnlyRecorded(Activity $activity, SearchFilter $filter): ?bool175+ {176+$filterValue = (int) $filter->getFilterValue();177+$hasRecording = $activity->recording_state !== Activity::RECORDING_OFF;178+179+return match ($filterValue) {180+1 => $hasRecording ? null : false, // Only recorded181+2 => ! $hasRecording ? null : false, // Only non-recorded182+default => null,183+ };184+ }185+186+private function checkStageId(Activity $activity, SearchFilter $filter): ?bool187+ {188+$stageId = $activity->getStage()?->getUuid();189+if ($stageId === null) {190+return null; // No stage, let ES handle191+ }192+193+return $filter->getFilterValue() === $stageId ? null : false;194+ }195+196+private function checkStartDate(Activity $activity, SearchFilter $filter): ?bool197+ {198+$startTime = $activity->getActualStartTime();199+if ($startTime === null) {200+return null;201+ }202+203+$filterDate = Carbon::parse($filter->getFilterValue());204+205+return $startTime->gte($filterDate) ? null : false;206+ }207+208+private function checkEndDate(Activity $activity, SearchFilter $filter): ?bool209+ {210+$endTime = $activity->getActualEndTime();211+if ($endTime === null) {212+return null;213+ }214+215+$filterDate = Carbon::parse($filter->getFilterValue())->endOfDay();216+217+return $endTime->lte($filterDate) ? null : false;218+ }219+220+private function checkLanguages(Activity $activity, SearchFilter $filter): ?bool221+ {222+$activityLanguage = $activity->getLanguageCode();223+if ($activityLanguage === null) {224+return null;225+ }226+227+// Filter values are always base language codes (e.g., 'en', 'fr').228+// Extract base code from activity locale (e.g., en_GB -> en) to match ES query behavior.229+// See LanguageFilterDefinition::getQueries() which uses regex: $language . '_[a-z]{2}'230+$activityLangCode = explode('_', $activityLanguage)[0];231+$filterLanguage = $filter->getFilterValue();232+233+return $activityLangCode === $filterLanguage ? null : false;69 }234 }70}235}</selection>” selected. Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
You said
I’m on page “<tabTitle>Jy 20493 smart instant nudge pre filtering by niko</tabTitle>” with “<selection>@@ -4,16 +4,17 @@445namespace Jiminny\Component\Nudge\Job;5namespace Jiminny\Component\Nudge\Job;667+use Carbon\Carbon;7use Illuminate\Bus\Queueable;8use Illuminate\Bus\Queueable;8use Illuminate\Contracts\Queue\ShouldQueue;9use Illuminate\Contracts\Queue\ShouldQueue;9-use Illuminate\Database\Eloquent\Builder;10use Illuminate\Foundation\Bus\Dispatchable;10use Illuminate\Foundation\Bus\Dispatchable;11use Illuminate\Queue\InteractsWithQueue;11use Illuminate\Queue\InteractsWithQueue;12use Illuminate\Queue\SerializesModels;12use Illuminate\Queue\SerializesModels;13use Illuminate\Support\Facades\Log;13use Illuminate\Support\Facades\Log;14use Jiminny\Component\Queue\Constants;14use Jiminny\Component\Queue\Constants;15use Jiminny\Models\Activity;15use Jiminny\Models\Activity;16use Jiminny\Models\Activity\Search;16use Jiminny\Models\Activity\Search;17+use Jiminny\Models\Activity\SearchFilter;17use Jiminny\Models\Nudge;18use Jiminny\Models\Nudge;18use Jiminny\Models\Team;19use Jiminny\Models\Team;1920@@ -34,37 +35,201 @@343535public function handle(): void36public function handle(): void36 {37 {37-/** @var Activity $activity */38+$activity = Activity::with(['user.group'])->uuid($this->activityUuid, false)->firstOrFail();38-$activity = Activity::with(['user'])->uuid($this->activityUuid, false)->firstOrFail();39-40-/** @var Team $team */41$team = Team::with(['users'])->findOrFail($activity->user->team_id);39$team = Team::with(['users'])->findOrFail($activity->user->team_id);424043- Log::info(__METHOD__ . " Running for team $team->id.", [44-'activity_id' => $activity->id,45-'activity_uuid' => $this->activityUuid,46-'team_id' => $team->id,47- ]);48-49$usersIds = $team->users->pluck('id')->toArray();41$usersIds = $team->users->pluck('id')->toArray();504251-$searchesWithImmediateNudges = Activity\Search::with(['nudges'])43+$searchesWithImmediateNudges = Activity\Search::with([44+'nudges' => fn ($q) => $q->where('frequency', Nudge::FREQ_INSTANTLY),45+'filters',46+ ])52 ->whereIn('user_id', $usersIds)47 ->whereIn('user_id', $usersIds)53- ->whereHas('nudges', function (Builder $query) {48+ ->whereHas('nudges', fn ($q) => $q->where('frequency', Nudge::FREQ_INSTANTLY))54-$query->where('frequency', Nudge::FREQ_INSTANTLY);49+ ->get();55- })->get();50+51+$totalSearches = $searchesWithImmediateNudges->count();52+$skippedCount = 0;53+54+$searchesWithImmediateNudges->each(function (Search $search) use ($activity, &$skippedCount): void {55+$matchResult = $this->activityMightMatchSearch($activity, $search);565657-$searchesWithImmediateNudges->each(function (Search $search): void {57+if (! $matchResult['matches']) {58-$search->nudges->each(function (Nudge $nudge): void {58+$skippedCount++;59-// Filter only nudges that are set to be sent instantly59+ Log::info('Pre-filter skipped nudge dispatch', [60-if ($nudge->frequency === Nudge::FREQ_INSTANTLY) {60+'activity_uuid' => $activity->getUuid(),61- Log::info("Dispatching ProcessNudgeSearchJob for nudge $nudge->id.");61+'search_id' => $search->getId(),62+'mismatched_filter' => $matchResult['mismatch_reason'],63+'filter_value' => $matchResult['filter_value'],64+ ]);626563- ProcessNudgeSearchJob::dispatch($nudge);66+return;67+ }646865- Log::info("ProcessNudgeSearchJob dispatched for nudge $nudge->id.");69+$search->nudges->each(fn ($nudge) => ProcessNudgeSearchJob::dispatch($nudge));66- }67- });68 });70 });71+72+if ($totalSearches > 0) {73+ Log::info('Nudge pre-filter results', [74+'activity_uuid' => $activity->getUuid(),75+'total_searches' => $totalSearches,76+'skipped' => $skippedCount,77+'dispatched' => $totalSearches - $skippedCount,78+'skip_rate' => round(($skippedCount / $totalSearches) * 100, 2) . '%',79+ ]);80+ }81+ }82+83+private function activityMightMatchSearch(Activity $activity, Search $search): array84+ {85+foreach ($search->filters as $filter) {86+$filterName = $filter->getFilterProperty();87+88+$result = match ($filterName) {89+'group_id' => $this->checkGroupId($activity, $filter),90+'user_id' => $this->checkUserId($activity, $filter),91+'channel_id' => $this->checkChannelId($activity, $filter),92+'provider_id' => $this->checkProviderId($activity, $filter),93+'category_id' => $this->checkCategoryId($activity, $filter),94+'min_duration' => $this->checkMinDuration($activity, $filter),95+'max_duration' => $this->checkMaxDuration($activity, $filter),96+'not_logged' => $this->checkNotLogged($activity, $filter),97+'only_recorded' => $this->checkOnlyRecorded($activity, $filter),98+'languages' => $this->checkLanguages($activity, $filter),99+'stage_id' => $this->checkStageId($activity, $filter),100+'start_date' => $this->checkStartDate($activity, $filter),101+'end_date' => $this->checkEndDate($activity, $filter),102+default => null, // Unknown filter - can't pre-check, assume might match103+ };104+105+if ($result === false) {106+return [107+'matches' => false,108+'mismatch_reason' => $filterName,109+'filter_value' => $filter->getFilterValue(),110+ ];111+ }112+ }113+114+return ['matches' => true];115+ }116+117+private function checkGroupId(Activity $activity, SearchFilter $filter): ?bool118+ {119+$groupUuid = $activity->user->getGroup()?->getUuid();120+if ($groupUuid === null) {121+return null;122+ }123+124+return $filter->getFilterValue() === $groupUuid ? null : false;125+ }126+127+private function checkUserId(Activity $activity, SearchFilter $filter): ?bool128+ {129+return $filter->getFilterValue() === $activity->user->getUuid() ? null : false;130+ }131+132+private function checkChannelId(Activity $activity, SearchFilter $filter): ?bool133+ {134+return $filter->getFilterValue() === $activity->getType() ? null : false;135+ }136+137+private function checkProviderId(Activity $activity, SearchFilter $filter): ?bool138+ {139+return $filter->getFilterValue() === $activity->getProvider() ? null : false;140+ }141+142+private function checkCategoryId(Activity $activity, SearchFilter $filter): ?bool143+ {144+$categoryId = $activity->getCategory()?->getUuid();145+if ($categoryId === null) {146+return null;147+ }148+149+return $filter->getFilterValue() === $categoryId ? null : false;150+ }151+152+private function checkMinDuration(Activity $activity, SearchFilter $filter): ?bool153+ {154+return $activity->getDuration() >= (float) $filter->getFilterValue() ? null : false;155+ }156+157+private function checkMaxDuration(Activity $activity, SearchFilter $filter): ?bool158+ {159+return $activity->getDuration() <= (float) $filter->getFilterValue() ? null : false;160+ }161+162+private function checkNotLogged(Activity $activity, SearchFilter $filter): ?bool163+ {164+if (! $filter->getFilterValue()) {165+return null;166+ }167+168+$isLogged = $activity->getCrmProviderId() !== null;169+$isInternal = $activity->isInternal();170+171+return (! $isLogged || $isInternal) ? null : false;172+ }173+174+private function checkOnlyRecorded(Activity $activity, SearchFilter $filter): ?bool175+ {176+$filterValue = (int) $filter->getFilterValue();177+$hasRecording = $activity->recording_state !== Activity::RECORDING_OFF;178+179+return match ($filterValue) {180+1 => $hasRecording ? null : false, // Only recorded181+2 => ! $hasRecording ? null : false, // Only non-recorded182+default => null,183+ };184+ }185+186+private function checkStageId(Activity $activity, SearchFilter $filter): ?bool187+ {188+$stageId = $activity->getStage()?->getUuid();189+if ($stageId === null) {190+return null; // No stage, let ES handle191+ }192+193+return $filter->getFilterValue() === $stageId ? null : false;194+ }195+196+private function checkStartDate(Activity $activity, SearchFilter $filter): ?bool197+ {198+$startTime = $activity->getActualStartTime();199+if ($startTime === null) {200+return null;201+ }202+203+$filterDate = Carbon::parse($filter->getFilterValue());204+205+return $startTime->gte($filterDate) ? null : false;206+ }207+208+private function checkEndDate(Activity $activity, SearchFilter $filter): ?bool209+ {210+$endTime = $activity->getActualEndTime();211+if ($endTime === null) {212+return null;213+ }214+215+$filterDate = Carbon::parse($filter->getFilterValue())->endOfDay();216+217+return $endTime->lte($filterDate) ? null : false;218+ }219+220+private function checkLanguages(Activity $activity, SearchFilter $filter): ?bool221+ {222+$activityLanguage = $activity->getLanguageCode();223+if ($activityLanguage === null) {224+return null;225+ }226+227+// Filter values are always base language codes (e.g., 'en', 'fr').228+// Extract base code from activity locale (e.g., en_GB -> en) to match ES query behavior.229+// See LanguageFilterDefinition::getQueries() which uses regex: $language . '_[a-z]{2}'230+$activityLangCode = explode('_', $activityLanguage)[0];231+$filterLanguage = $filter->getFilterValue();232+233+return $activityLangCode === $filterLanguage ? null : false;69 }234 }70}235}</selection>” selected.
Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
Expand
Listen
Gemini said
Gemini said
This code selection introduces a
pre-filtering mechanism
to the
Jiminny\Component\Nudge\Job
namespace. The primary goal is to optimize performance by validating an activity against search criteria in-memory before dispatching costly background jobs.
Core Functionality Changes
Core Functionality Changes
Selective Loading:
The
handle()
method now eager-loads
user.group
for activities and specifically filters for
FREQ_INSTANTLY
nudges and their associated search filters.
Pre-Dispatch Validation:
Instead of dispatching jobs for every instant nudge, the system now calls
activityMightMatchSearch()
.
Short-Circuiting:
If an activity fails a pre-filter check (e.g., mismatched user ID or duration), the job dispatch is skipped, and the event is logged with the specific mismatch reason.
Performance Metrics:
Adds summary logging at the end of the process to track:
Total searches processed.
Number of skipped dispatches.
The "Skip Rate" percentage.
Implemented Filter Checks
Implemented Filter Checks
The logic includes a
match
expression to validate various activity attributes against
SearchFilter
values:
Identity & Metadata:
Matches for
group_id
,
user_id
,
channel_id
, and
provider_id
.
Temporal & Duration:
* Validates
min_duration
and
max_duration
.
Checks
start_date
and
end_date
using Carbon parsing.
Activity State:
*
Logging:
Determines if an activity is logged to a CRM or is internal via
checkNotLogged
.
Recording:
Uses
checkOnlyRecorded
to filter based on whether a recording exists.
Categorization:
Checks for
category_id
,
stage_id
, and
languages
.
Note:
The language check specifically extracts base codes (e.g.,
en
from
en_GB
) to align with Elasticsearch behavior.
Logic Design
Logic Design
Nullable Returns:
Filter methods return
null
if a match is possible (or cannot be determined), and
false
only when a definitive mismatch is found.
Safe Fallback:
If a filter type is unknown (
default
), the system assumes a match and proceeds to dispatch, ensuring no false negatives.
Good response
Bad response
Share & export
Copy
Show more options
Copy prompt
You said what is the logic behind diff. Act as code reviewer. First review the changes then explain it and then evaluate. Try to find potential issues and bottlenecks
You said
what is the logic behind diff. Act as code reviewer. First review the changes then explain it and then evaluate. Try to find potential issues and bottlenecks
Expand
Listen
Show more options
Show thinking
Gemini said
Gemini said
Here is a review of the changes provided in the diff, broken down by your requested structure.
1. Review of Changes
1. Review of Changes
This PR refactors the
ProcessNudgeSearchJob
dispatching mechanism within the
handle()
method.
Query Optimization:
Eager loads necessary relationships (
user.group
,
filters
) and scopes the
nudges
relationship at the database level to only fetch
FREQ_INSTANTLY
records.
In-Memory Filtering:
Introduces a pre-filtering mechanism (
activityMightMatchSearch
) that checks the
Activity
against
SearchFilter
criteria before deciding to dispatch a job.
Helper Methods:
Adds 13 private
check*
methods to handle the specific comparison logic for different filter types (e.g., duration, dates, categories, stages).
Observability:
Adds structured logging to record exactly why a nudge was skipped and outputs a summary report (total, skipped, dispatched, skip rate) at the end of the execution.
2. Explanation of Logic
2. Explanation of Logic
The core philosophy of this change is
"veto-based short-circuiting"
.
Previously, the job fetched all searches with instant nudges for a team's users and blindly dispatched a queue job for every single one. The heavy lifting of deciding if the activity actually matched the search was likely deferred to the queue worker and Elasticsearch.
Now, the code evaluates the filters in the current process:
It iterates through each
Search
and its associated
SearchFilter
s.
It routes the filter to a specific
check*
method using a
match
expression based on the filter's property name.
The Veto:
The
check*
methods are designed to return
false
only if there is an absolute mismatch
(e.g., the filter requires a minimum duration of 10, but the activity is 5).
The Pass:
If the filter matches, or if the activity lacks the data needed to make a firm decision (e.g., no stage is assigned, or the filter type is unrecognized), the method returns
null
. This acts as a pass, delegating the final strict evaluation to Elasticsearch later in the pipeline.
If any filter returns
false
, the search is skipped, saving a queue dispatch.
3. Evaluation
3. Evaluation
Overall, this is a
highly effective performance optimization
.
Pros:
It significantly reduces queue bloat. By filtering out obvious mismatches in-memory, you save the overhead of serializing, dispatching, picking up, and processing jobs that are destined to fail or do nothing. The use of
match
makes the routing exceptionally clean, and the nullable return design is a smart way to avoid false negatives.
Cons/Trade-offs:
You are trading background queue worker time for a slight increase in synchronous memory and CPU usage on the current job. However, queue I/O is almost always more expensive than simple in-memory comparisons, making this a worthwhile trade.
4. Potential Issues & Bottlenecks
4. Potential Issues & Bottlenecks
While the logic is sound, there are a few architectural bottlenecks and risks introduced or maintained in this diff:
Potential N+1 Query / Lazy Loading Issues:
In the
handle
method, the activity is loaded with
Activity::with(['user.group'])
. However, inside your new
check*
methods, you are calling:
$activity->getCategory()?->getUuid()
$activity->getStage()?->getUuid()
If
category
and
stage
are Eloquent relationships and are not eager-loaded on the original
$activity
model, calling these methods inside a loop of
$totalSearches
will trigger lazy-loaded database queries.
Fix:
Update line 38 to:
$activity = Activity::with(['user.group', 'category', 'stage'])->...
Massive Memory Consumption (Pre-existing but critical):
Lines 39-41:
PHP
Download code
Copy code
$team
= Team::with([
'users'
])->findOrFail(
$activity
->user->team_id);
$usersIds
=
$team
->users->pluck(
'id'
)->toArray();
If a team has thousands of users,
Team::with(['users'])
hydrates thousands of full Eloquent User models into memory just to extract their IDs.
Fix:
Bypass hydrating the models entirely by querying the relationship directly:
$usersIds = $team->users()->pluck('id')->toArray();
Repeated Carbon Parsing in Loops:
In
checkStartDate
and
checkEndDate
, you parse the filter date:
Carbon::parse($filter->getFilterValue())
. If the same date filter applies to multiple searches, Carbon is being instantiated repeatedly in the loop. While Carbon is relatively fast, doing this hundreds of times adds unnecessary CPU cycles.
Fix:
This is a minor nitpick, but if performance is the absolute goal, you could memoize/cache the parsed filter values within the job.
Loose Type Comparisons:
In methods like
checkChannelId
or
checkLanguages
, you are using strict equality (
===
). Ensure that
$filter->getFilterValue()
(which is typically returned as a string from a database payload) matches the exact type returned by
$activity->getType()
or
$activityLangCode
. If one is an integer
1
and the other is a string
"1"
, the strict check will return
false
, incorrectly preventing the nudge from sending.
Good response
Bad response
Share & export
Copy
Show more options
Copy prompt
Edit
You said what would be your suggestion?
You said
what would be your suggestion?
Listen
Show more options
Show thinking
Gemini said
Gemini said
Here are actionable suggestions to address the potential issues and bottlenecks identified in the review. These optimizations focus on reducing memory footprint, preventing lazy-loading, and ensuring data type resilience.
1. Fix the N+1 Query Risk (Eager Loading)
1. Fix the N+1 Query Risk (Eager Loading)
Your
checkCategoryId
and
checkStageId
methods call
$activity->getCategory()
and
$activity->getStage()
. If these relationships aren't eager-loaded, Laravel will execute a new database query for every check inside the loop.
Suggestion:
Add
category
and
stage
to the initial eager-load array.
PHP...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
18578
|
803
|
7
|
2026-05-11T11:35:04.714365+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778499304714_m2.jpg...
|
PhpStorm
|
faVsco.js – HandleHubspotRateLimit.php
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhostormcodeProiectD MeetingBo1• Middleware© Playb PhostormcodeProiectD MeetingBo1• Middleware© PlaybackController.php© kateLimitea.ongD Streaming• _ leamC Telephonv(C)PaqinationState.phpC) MatchCrmData.php(C) Providev D Userclass Handl eHubspotRateLimitc) ChangeEmailjob.phpDeactivateUserJob.ph@ SetupDefaultSavedSe: 24@ SvncTolntercom.phppubltry unctzon handle (obJect sJ0b, callable Snext): voacSnext(100)"} catch (RateLimitException $e) {Sdelav = max( value: self::MIN RETRY DELAY. min(se->aetRic) suncirop anhat.ono(C) SvncToUserPilot.oho// Add jitter to prevent thundering herd problem by raSdelay += random_ int(0, self::JITTER_SECONDS) :© BaseProcessingJob.phpC)Dummv.lob.ohoSattemnts = Cioh-Sattemnts0.© ImportRecallAlRecordings so(cImnortRemoteTrack.loh.nif (Sattempts <= 3| Sattempts % 10 === 0) 1Loa.• infod messace: ![Handl eHuhsnotRatel imi+ Rate 1C Job.php© JobDispatcher.php© JobDispatcherinterface.p 34© PurgeSoftDeletedOpporti• SqsVisibilityControl.phpv D ListenersvM Activitios'job_class' => $job::class,'attempts' => Sattempts,'retry_after' => $e->getRetryAfterO'delay' => $delay,vM Activity DrovidorSiob->release ($delay):Local ChandesChanges 12 tilesShelConsole,= env.locall anol© Client.php app/Services/Crm/Hubspot(C) HandleHlubsootRateLimit.oho aoo/.lobs/Middleware© HandleHubspotRateLimitTest.php tests/Unit/Jobs/Middleware(1HubsootClientinterface.oho aon/Services/Crm/Hubsoot|© HubspotPaginationService.php app/Services/Crm/Hubspot/Pagination© JiminnyDebugCommand.php app/Console/Commandsphp logging.php config© MatchActivityCrmData.php app/Jobs/Crm© PaginationState.php app/Services/Crm/Hubspot/PaginationRateLimitException.php app/Exceptions(et Patel imitExceptionTest.php tests/Unit/Exceptions/ Unversioned Files 9 filesE.env.nikilocal appE env.other aprС) CanAccessAiReportsTest.php tests/Unit/Policies© CreateMockAskJiminnvReportResultCommand.php app/Console/Commands/RepE favicon.ico publidE ids.txt appT raw sal querv sal [EMAIL] app/Console/Commands/Crm/HubspotSide-by-side v8 35f036ac app/Exceptions/RateLimitEdeclare(strict types=1)namespace Jiminny Exceptionsclass RateLimitException exteniM_WE?HOOK FILTERING IMPLEMENTATION.md a00• Preparation tor kerl.. In 2o m100% 2• Mon 11 May 14:35:04+0 ..=laravel.log X 4 SF (jiminny@localhost]4 HS_local jiminny@localhost]# console [PRol)# console [eu)© CachedCrmServiceDecorator.phpA console [STAGING]429x 5 Cc WTIYH44, matches in 14 flledFile mask: *-php• RateLimitexceptionx 5 Cc WIn ProiectModuleDirectoryen {"account_id":1372,"updated_ wM454 ^Y{"total":3, "fixed":0, "failed":3} {"correlationnd::run Memory usage before starting command {"nd::run Memory usage before starting command {"cing polling service1"correlac1on10: 754015use Jiminny Excentions RateLimitExceotionMatchActivitvCrmData.ono 16if (l $e instanceof RateLimitException)use liminnv Sycentions Ratel imit Excention)irea polling lock 1"explres ac: 2020-05-111159ing new client credentials tokenGuzzleException|HttpBadRequestException|JsonException|RateLimitException|UnexpectedValueException $exception GenerateActiorGenerateAiActivityTypeJob.php 1910::run memory usage tor commano ""commano":"7nd::run Memory usage for coRateLimitExceptionGenerateAiCallScoring.lob.nhn 17RateLimitExceptionCummarizoTranccrintion loh nhn 161d::run Memory usage before startina command 'nd::run Memory usage for command {"command": "cncuzzieexceotion huobackeouestexceotonjsonexceotion kateLimitexceptonUnexpecteavalueexceotonsexceorouclass RateLimitException extends RuntimeExceptionPatol imitEycantion nhn QnanolemuospotkateLimit.ong o* Job middleware that catches RateLimitException from HubSpot APl callsnd::run Memory usage before starting command {"nd::run Memory usage for command t"command":"cr{"correlation_id":"954d156d-8a4f-4592-a046catch (RateLimitexception seMatchActivitvermData.ono apo/Jobs/Crmuse iLuminate Contracts Queve ShouldBeunique:use Illuminate \Contracts \Queue \ShouldQueue;use luuminate Database Connection:use Illuminate \Queue \InteractsWithQueue;use Illuminate Queue SerializesModels:use Tlluminate Sunnort Facades Loa:use Jiminny \Component \Queue\Constants;use Jiminny \Exceptions\InvalidArgumentException;use Jiminny\Exceptions \RateLimitException;use Jiminny (Jobs\Job;use Jiminny\Jobs\Middleware\HandleHubspotRateLimituse Jiminny Models\Activity:uce liminnv Models Crm Confiquration:it versionamespace Jiminny Exceptionsse hrowadleuse Jiminny keposicores Acc1vlcykepos1cory*use Jiminny\Services\Crm\CrmActivityService:use Psr\Container\ContainerExceptionInterface:use Psr\Container\NotFoundExceptionInterface:lass RateLimitExcention extends RuntimeExcentionuse hrowablerpublic function __construct(Strina Smessage =private readonly int $retryAfter = 1,Throwahil e Sarevious = nuiclass MatchActivityCrmData extends Job implements ShouldOueue. ShouldBeUniquenarent.• construct(Smecsade. A Snrevious)•use Interactswithoueveuse SerializesModels:public function getRetryAfterO: intOnen recults in now tabOnen in Sind Windownotunn may/Cthic-snotnvAfton 1)•Hubspot Rate Limit Re3. Middleware behavior is healthy vSamole line[HandleHubspotRateLimit] Rate limit caught, releasing job with delay ("attempts":1,"retry_after":1,"d•delay=5 is retry after (1) + jitter (random 0-S) = within [1, 61•Other releases in the log show delay: 4, 5 etc. - jitter is varying as expected•All attempts:1 - no jobs reached 2+ retries, meaning subsequent attempts after release succeeded on the next pass4. No anti-patterns triggered V• Zero Failed to match GRM data lines = the instanceof RateLimitExcention filter in MatchActivitvCrmData::handlZero permanently failed lines = no job hit retryUntil - everything completed within window• Zero using default warnings = parseRetryAfter always extracted a known keyword from the messageWhat this means for productionEytranolatina to the 100k cconario.43% of rate-limits served from cache (3/7) — and that's at LOW load. At storm scale, this raticsed 92% of your quota. Quota resets May 12, 11:00 AM GMT+3.Ask anytning (dtl<> CodeClaude Opus 4.7 Medium2 differencesfo 4 spaces...
|
NULL
|
-8255271704525131086
|
NULL
|
click
|
ocr
|
NULL
|
PhostormcodeProiectD MeetingBo1• Middleware© Playb PhostormcodeProiectD MeetingBo1• Middleware© PlaybackController.php© kateLimitea.ongD Streaming• _ leamC Telephonv(C)PaqinationState.phpC) MatchCrmData.php(C) Providev D Userclass Handl eHubspotRateLimitc) ChangeEmailjob.phpDeactivateUserJob.ph@ SetupDefaultSavedSe: 24@ SvncTolntercom.phppubltry unctzon handle (obJect sJ0b, callable Snext): voacSnext(100)"} catch (RateLimitException $e) {Sdelav = max( value: self::MIN RETRY DELAY. min(se->aetRic) suncirop anhat.ono(C) SvncToUserPilot.oho// Add jitter to prevent thundering herd problem by raSdelay += random_ int(0, self::JITTER_SECONDS) :© BaseProcessingJob.phpC)Dummv.lob.ohoSattemnts = Cioh-Sattemnts0.© ImportRecallAlRecordings so(cImnortRemoteTrack.loh.nif (Sattempts <= 3| Sattempts % 10 === 0) 1Loa.• infod messace: ![Handl eHuhsnotRatel imi+ Rate 1C Job.php© JobDispatcher.php© JobDispatcherinterface.p 34© PurgeSoftDeletedOpporti• SqsVisibilityControl.phpv D ListenersvM Activitios'job_class' => $job::class,'attempts' => Sattempts,'retry_after' => $e->getRetryAfterO'delay' => $delay,vM Activity DrovidorSiob->release ($delay):Local ChandesChanges 12 tilesShelConsole,= env.locall anol© Client.php app/Services/Crm/Hubspot(C) HandleHlubsootRateLimit.oho aoo/.lobs/Middleware© HandleHubspotRateLimitTest.php tests/Unit/Jobs/Middleware(1HubsootClientinterface.oho aon/Services/Crm/Hubsoot|© HubspotPaginationService.php app/Services/Crm/Hubspot/Pagination© JiminnyDebugCommand.php app/Console/Commandsphp logging.php config© MatchActivityCrmData.php app/Jobs/Crm© PaginationState.php app/Services/Crm/Hubspot/PaginationRateLimitException.php app/Exceptions(et Patel imitExceptionTest.php tests/Unit/Exceptions/ Unversioned Files 9 filesE.env.nikilocal appE env.other aprС) CanAccessAiReportsTest.php tests/Unit/Policies© CreateMockAskJiminnvReportResultCommand.php app/Console/Commands/RepE favicon.ico publidE ids.txt appT raw sal querv sal [EMAIL] app/Console/Commands/Crm/HubspotSide-by-side v8 35f036ac app/Exceptions/RateLimitEdeclare(strict types=1)namespace Jiminny Exceptionsclass RateLimitException exteniM_WE?HOOK FILTERING IMPLEMENTATION.md a00• Preparation tor kerl.. In 2o m100% 2• Mon 11 May 14:35:04+0 ..=laravel.log X 4 SF (jiminny@localhost]4 HS_local jiminny@localhost]# console [PRol)# console [eu)© CachedCrmServiceDecorator.phpA console [STAGING]429x 5 Cc WTIYH44, matches in 14 flledFile mask: *-php• RateLimitexceptionx 5 Cc WIn ProiectModuleDirectoryen {"account_id":1372,"updated_ wM454 ^Y{"total":3, "fixed":0, "failed":3} {"correlationnd::run Memory usage before starting command {"nd::run Memory usage before starting command {"cing polling service1"correlac1on10: 754015use Jiminny Excentions RateLimitExceotionMatchActivitvCrmData.ono 16if (l $e instanceof RateLimitException)use liminnv Sycentions Ratel imit Excention)irea polling lock 1"explres ac: 2020-05-111159ing new client credentials tokenGuzzleException|HttpBadRequestException|JsonException|RateLimitException|UnexpectedValueException $exception GenerateActiorGenerateAiActivityTypeJob.php 1910::run memory usage tor commano ""commano":"7nd::run Memory usage for coRateLimitExceptionGenerateAiCallScoring.lob.nhn 17RateLimitExceptionCummarizoTranccrintion loh nhn 161d::run Memory usage before startina command 'nd::run Memory usage for command {"command": "cncuzzieexceotion huobackeouestexceotonjsonexceotion kateLimitexceptonUnexpecteavalueexceotonsexceorouclass RateLimitException extends RuntimeExceptionPatol imitEycantion nhn QnanolemuospotkateLimit.ong o* Job middleware that catches RateLimitException from HubSpot APl callsnd::run Memory usage before starting command {"nd::run Memory usage for command t"command":"cr{"correlation_id":"954d156d-8a4f-4592-a046catch (RateLimitexception seMatchActivitvermData.ono apo/Jobs/Crmuse iLuminate Contracts Queve ShouldBeunique:use Illuminate \Contracts \Queue \ShouldQueue;use luuminate Database Connection:use Illuminate \Queue \InteractsWithQueue;use Illuminate Queue SerializesModels:use Tlluminate Sunnort Facades Loa:use Jiminny \Component \Queue\Constants;use Jiminny \Exceptions\InvalidArgumentException;use Jiminny\Exceptions \RateLimitException;use Jiminny (Jobs\Job;use Jiminny\Jobs\Middleware\HandleHubspotRateLimituse Jiminny Models\Activity:uce liminnv Models Crm Confiquration:it versionamespace Jiminny Exceptionsse hrowadleuse Jiminny keposicores Acc1vlcykepos1cory*use Jiminny\Services\Crm\CrmActivityService:use Psr\Container\ContainerExceptionInterface:use Psr\Container\NotFoundExceptionInterface:lass RateLimitExcention extends RuntimeExcentionuse hrowablerpublic function __construct(Strina Smessage =private readonly int $retryAfter = 1,Throwahil e Sarevious = nuiclass MatchActivityCrmData extends Job implements ShouldOueue. ShouldBeUniquenarent.• construct(Smecsade. A Snrevious)•use Interactswithoueveuse SerializesModels:public function getRetryAfterO: intOnen recults in now tabOnen in Sind Windownotunn may/Cthic-snotnvAfton 1)•Hubspot Rate Limit Re3. Middleware behavior is healthy vSamole line[HandleHubspotRateLimit] Rate limit caught, releasing job with delay ("attempts":1,"retry_after":1,"d•delay=5 is retry after (1) + jitter (random 0-S) = within [1, 61•Other releases in the log show delay: 4, 5 etc. - jitter is varying as expected•All attempts:1 - no jobs reached 2+ retries, meaning subsequent attempts after release succeeded on the next pass4. No anti-patterns triggered V• Zero Failed to match GRM data lines = the instanceof RateLimitExcention filter in MatchActivitvCrmData::handlZero permanently failed lines = no job hit retryUntil - everything completed within window• Zero using default warnings = parseRetryAfter always extracted a known keyword from the messageWhat this means for productionEytranolatina to the 100k cconario.43% of rate-limits served from cache (3/7) — and that's at LOW load. At storm scale, this raticsed 92% of your quota. Quota resets May 12, 11:00 AM GMT+3.Ask anytning (dtl<> CodeClaude Opus 4.7 Medium2 differencesfo 4 spaces...
|
18576
|
NULL
|
NULL
|
NULL
|
|
23671
|
1001
|
14
|
2026-05-12T08:22:22.376581+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778574142376_m2.jpg...
|
PhpStorm
|
faVsco.js – console [PROD]
|
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
8
1
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Carbon;
use Jiminny\Traits\RequiresUUID;
/**
* Jiminny\Models\AutomatedReportResult
*
* @property int $id
* @property string $uuid
* @property int $report_id
* @property string|null $name
* @property int $status
* @property int $reason
* @property string $media_type
* @property int|null $parent_id
* @property array|null $payload
* @property array|null $response
* @property Carbon|null $requested_at
* @property Carbon|null $generated_at
* @property Carbon|null $sent_at
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
* @property-read \Jiminny\Models\AutomatedReport $report
* @property-read AutomatedReportResult|null $parent
* @property-read \Illuminate\Database\Eloquent\Collection<int, AutomatedReportResult> $children
*/
class AutomatedReportResult extends Model
{
use RequiresUUID;
/**
* Status constants
*/
public const int STATUS_DEFAULT = 0;
public const int STATUS_REQUESTED = 1;
public const int STATUS_GENERATED = 2;
public const int STATUS_SENT = 3;
public const int STATUS_FAILED = 4;
/**
* Reason constants
*/
public const int REASON_DEFAULT = 0;
public const int REASON_NOT_ENOUGH_ACTIVITIES = 1;
public const int REASON_PROPHET_API_ERROR = 2;
protected $table = 'automated_report_results';
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'report_id',
'name',
'status',
'reason',
'media_type',
'parent_id',
'payload',
'response',
'requested_at',
'generated_at',
'sent_at',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'payload' => 'array',
'response' => 'array',
'requested_at' => 'datetime',
'generated_at' => 'datetime',
'sent_at' => 'datetime',
];
}
/**
* Get the automated report that owns this result.
*
* @return BelongsTo
*/
public function report(): BelongsTo
{
return $this->belongsTo(AutomatedReport::class, 'report_id')->withTrashed();
}
/**
* Get the parent report result.
*
* @return BelongsTo
*/
public function parent(): BelongsTo
{
return $this->belongsTo(self::class, 'parent_id');
}
/**
* Get the child report results.
*
* @return HasMany
*/
public function children(): HasMany
{
return $this->hasMany(self::class, 'parent_id');
}
/**
* Get the ID of the automated report result.
*
* @return int
*/
public function getId(): int
{
return $this->getAttribute('id');
}
/**
* Get the UUID of the automated report result.
*
* @return string
*/
public function getUuid(): string
{
return $this->getAttribute('id_string');
}
/**
* Get the report ID of the automated report result.
*
* @return int
*/
public function getReportId(): int
{
return $this->getAttribute('report_id');
}
/**
* Get the name of the automated report result.
*
* @return ?string
*/
public function getName(): ?string
{
return $this->getAttribute('name');
}
/**
* Get the status of the automated report result.
*
* @return int
*/
public function getStatus(): int
{
return $this->getAttribute('status');
}
/**
* Get the reason of the automated report result.
*
* @return int
*/
public function getReason(): int
{
return $this->getAttribute('reason');
}
/**
* Get the media type of the automated report result.
*
* @return string
*/
public function getMediaType(): ?string
{
return $this->getAttribute('media_type');
}
/**
* Get the parent ID of the automated report result.
*
* @return int|null
*/
public function getParentId(): ?int
{
return $this->getAttribute('parent_id');
}
/**
* Get the payload of the automated report result.
*
* @return array|null
*/
public function getPayload(): ?array
{
return $this->getAttribute('payload');
}
/**
* Get the response of the automated report result.
*
* @return array|null
*/
public function getResponse(): ?array
{
return $this->getAttribute('response');
}
/**
* Get the requested at date of the automated report result.
*
* @return Carbon|null
*/
public function getRequestedAt(): ?Carbon
{
return $this->getAttribute('requested_at');
}
/**
* Get the generated at date of the automated report result.
*
* @return Carbon|null
*/
public function getGeneratedAt(): ?Carbon
{
return $this->getAttribute('generated_at');
}
/**
* Get the sent at date of the automated report result.
*
* @return Carbon|null
*/
public function getSentAt(): ?Carbon
{
return $this->getAttribute('sent_at');
}
/**
* Get the created at date of the automated report result.
*
* @return Carbon
*/
public function getCreatedAt(): Carbon
{
return $this->getAttribute('created_at');
}
/**
* Get the updated at date of the automated report result.
*
* @return Carbon
*/
public function getUpdatedAt(): Carbon
{
return $this->getAttribute('updated_at');
}
/**
* Check if the report result is in requested status.
*
* @return bool
*/
public function isRequested(): bool
{
return $this->getStatus() === self::STATUS_REQUESTED;
}
/**
* Check if the report result is in generated status.
*
* @return bool
*/
public function isGenerated(): bool
{
return $this->getStatus() === self::STATUS_GENERATED;
}
/**
* Check if the report result is in sent status.
*
* @return bool
*/
public function isSent(): bool
{
return $this->getStatus() === self::STATUS_SENT;
}
/**
* Check if the report result is in failed status.
*
* @return bool
*/
public function isFailed(): bool
{
return $this->getStatus() === self::STATUS_FAILED;
}
public function getStatusLabel(): string
{
return match ($this->getStatus()) {
self::STATUS_REQUESTED => 'Requested',
self::STATUS_GENERATED => 'Generated',
self::STATUS_SENT => 'Sent',
self::STATUS_FAILED => 'Failed',
default => 'Default',
};
}
public function getReport(): AutomatedReport
{
return $this->getAttribute('report');
}
public function getFromDate(): ?Carbon
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['from_date'])) {
return null;
}
return Carbon::parse($payload['from_date']);
}
public function getToDate(): ?Carbon
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['to_date'])) {
return null;
}
return Carbon::parse($payload['to_date']);
}
public function getReportType(): ?string
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['report_type'])) {
return null;
}
return $payload['report_type'];
}
public function getGroups(): array
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['group_ids'])) {
return [];
}
return $payload['group_ids'];
}
public function getPdfUrl(): ?string
{
$response = $this->getResponse();
return $response['pdf_url'] ?? null;
}
public function getPodcastAudioUrl(): ?string
{
$response = $this->getResponse();
return $response['podcast_audio_url'] ?? null;
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny...
|
[{"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":"AXStaticText","text":"8","depth":4,"bounds":{"left":0.38297874,"top":0.10055866,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.3929521,"top":0.10055866,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.40226063,"top":0.10055866,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.4112367,"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.41855052,"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":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Support\\Carbon;\nuse Jiminny\\Traits\\RequiresUUID;\n\n/**\n * Jiminny\\Models\\AutomatedReportResult\n *\n * @property int $id\n * @property string $uuid\n * @property int $report_id\n * @property string|null $name\n * @property int $status\n * @property int $reason\n * @property string $media_type\n * @property int|null $parent_id\n * @property array|null $payload\n * @property array|null $response\n * @property Carbon|null $requested_at\n * @property Carbon|null $generated_at\n * @property Carbon|null $sent_at\n * @property Carbon|null $created_at\n * @property Carbon|null $updated_at\n * @property-read \\Jiminny\\Models\\AutomatedReport $report\n * @property-read AutomatedReportResult|null $parent\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, AutomatedReportResult> $children\n */\nclass AutomatedReportResult extends Model\n{\n use RequiresUUID;\n\n /**\n * Status constants\n */\n public const int STATUS_DEFAULT = 0;\n public const int STATUS_REQUESTED = 1;\n public const int STATUS_GENERATED = 2;\n public const int STATUS_SENT = 3;\n public const int STATUS_FAILED = 4;\n\n /**\n * Reason constants\n */\n public const int REASON_DEFAULT = 0;\n public const int REASON_NOT_ENOUGH_ACTIVITIES = 1;\n public const int REASON_PROPHET_API_ERROR = 2;\n\n protected $table = 'automated_report_results';\n\n /**\n * The attributes that are mass assignable.\n *\n * @var array<int, string>\n */\n protected $fillable = [\n 'report_id',\n 'name',\n 'status',\n 'reason',\n 'media_type',\n 'parent_id',\n 'payload',\n 'response',\n 'requested_at',\n 'generated_at',\n 'sent_at',\n ];\n\n /**\n * Get the attributes that should be cast.\n *\n * @return array<string, string>\n */\n protected function casts(): array\n {\n return [\n 'payload' => 'array',\n 'response' => 'array',\n 'requested_at' => 'datetime',\n 'generated_at' => 'datetime',\n 'sent_at' => 'datetime',\n ];\n }\n\n /**\n * Get the automated report that owns this result.\n *\n * @return BelongsTo\n */\n public function report(): BelongsTo\n {\n return $this->belongsTo(AutomatedReport::class, 'report_id')->withTrashed();\n }\n\n /**\n * Get the parent report result.\n *\n * @return BelongsTo\n */\n public function parent(): BelongsTo\n {\n return $this->belongsTo(self::class, 'parent_id');\n }\n\n /**\n * Get the child report results.\n *\n * @return HasMany\n */\n public function children(): HasMany\n {\n return $this->hasMany(self::class, 'parent_id');\n }\n\n /**\n * Get the ID of the automated report result.\n *\n * @return int\n */\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n /**\n * Get the UUID of the automated report result.\n *\n * @return string\n */\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n /**\n * Get the report ID of the automated report result.\n *\n * @return int\n */\n public function getReportId(): int\n {\n return $this->getAttribute('report_id');\n }\n\n /**\n * Get the name of the automated report result.\n *\n * @return ?string\n */\n public function getName(): ?string\n {\n return $this->getAttribute('name');\n }\n\n /**\n * Get the status of the automated report result.\n *\n * @return int\n */\n public function getStatus(): int\n {\n return $this->getAttribute('status');\n }\n\n /**\n * Get the reason of the automated report result.\n *\n * @return int\n */\n public function getReason(): int\n {\n return $this->getAttribute('reason');\n }\n\n /**\n * Get the media type of the automated report result.\n *\n * @return string\n */\n public function getMediaType(): ?string\n {\n return $this->getAttribute('media_type');\n }\n\n /**\n * Get the parent ID of the automated report result.\n *\n * @return int|null\n */\n public function getParentId(): ?int\n {\n return $this->getAttribute('parent_id');\n }\n\n /**\n * Get the payload of the automated report result.\n *\n * @return array|null\n */\n public function getPayload(): ?array\n {\n return $this->getAttribute('payload');\n }\n\n /**\n * Get the response of the automated report result.\n *\n * @return array|null\n */\n public function getResponse(): ?array\n {\n return $this->getAttribute('response');\n }\n\n /**\n * Get the requested at date of the automated report result.\n *\n * @return Carbon|null\n */\n public function getRequestedAt(): ?Carbon\n {\n return $this->getAttribute('requested_at');\n }\n\n /**\n * Get the generated at date of the automated report result.\n *\n * @return Carbon|null\n */\n public function getGeneratedAt(): ?Carbon\n {\n return $this->getAttribute('generated_at');\n }\n\n /**\n * Get the sent at date of the automated report result.\n *\n * @return Carbon|null\n */\n public function getSentAt(): ?Carbon\n {\n return $this->getAttribute('sent_at');\n }\n\n /**\n * Get the created at date of the automated report result.\n *\n * @return Carbon\n */\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n /**\n * Get the updated at date of the automated report result.\n *\n * @return Carbon\n */\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n /**\n * Check if the report result is in requested status.\n *\n * @return bool\n */\n public function isRequested(): bool\n {\n return $this->getStatus() === self::STATUS_REQUESTED;\n }\n\n /**\n * Check if the report result is in generated status.\n *\n * @return bool\n */\n public function isGenerated(): bool\n {\n return $this->getStatus() === self::STATUS_GENERATED;\n }\n\n /**\n * Check if the report result is in sent status.\n *\n * @return bool\n */\n public function isSent(): bool\n {\n return $this->getStatus() === self::STATUS_SENT;\n }\n\n /**\n * Check if the report result is in failed status.\n *\n * @return bool\n */\n public function isFailed(): bool\n {\n return $this->getStatus() === self::STATUS_FAILED;\n }\n\n public function getStatusLabel(): string\n {\n return match ($this->getStatus()) {\n self::STATUS_REQUESTED => 'Requested',\n self::STATUS_GENERATED => 'Generated',\n self::STATUS_SENT => 'Sent',\n self::STATUS_FAILED => 'Failed',\n default => 'Default',\n };\n }\n\n public function getReport(): AutomatedReport\n {\n return $this->getAttribute('report');\n }\n\n public function getFromDate(): ?Carbon\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['from_date'])) {\n return null;\n }\n\n return Carbon::parse($payload['from_date']);\n }\n\n public function getToDate(): ?Carbon\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['to_date'])) {\n return null;\n }\n\n return Carbon::parse($payload['to_date']);\n }\n\n public function getReportType(): ?string\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['report_type'])) {\n return null;\n }\n\n return $payload['report_type'];\n }\n\n public function getGroups(): array\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['group_ids'])) {\n return [];\n }\n\n return $payload['group_ids'];\n }\n\n public function getPdfUrl(): ?string\n {\n $response = $this->getResponse();\n\n return $response['pdf_url'] ?? null;\n }\n\n public function getPodcastAudioUrl(): ?string\n {\n $response = $this->getResponse();\n\n return $response['podcast_audio_url'] ?? null;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Support\\Carbon;\nuse Jiminny\\Traits\\RequiresUUID;\n\n/**\n * Jiminny\\Models\\AutomatedReportResult\n *\n * @property int $id\n * @property string $uuid\n * @property int $report_id\n * @property string|null $name\n * @property int $status\n * @property int $reason\n * @property string $media_type\n * @property int|null $parent_id\n * @property array|null $payload\n * @property array|null $response\n * @property Carbon|null $requested_at\n * @property Carbon|null $generated_at\n * @property Carbon|null $sent_at\n * @property Carbon|null $created_at\n * @property Carbon|null $updated_at\n * @property-read \\Jiminny\\Models\\AutomatedReport $report\n * @property-read AutomatedReportResult|null $parent\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, AutomatedReportResult> $children\n */\nclass AutomatedReportResult extends Model\n{\n use RequiresUUID;\n\n /**\n * Status constants\n */\n public const int STATUS_DEFAULT = 0;\n public const int STATUS_REQUESTED = 1;\n public const int STATUS_GENERATED = 2;\n public const int STATUS_SENT = 3;\n public const int STATUS_FAILED = 4;\n\n /**\n * Reason constants\n */\n public const int REASON_DEFAULT = 0;\n public const int REASON_NOT_ENOUGH_ACTIVITIES = 1;\n public const int REASON_PROPHET_API_ERROR = 2;\n\n protected $table = 'automated_report_results';\n\n /**\n * The attributes that are mass assignable.\n *\n * @var array<int, string>\n */\n protected $fillable = [\n 'report_id',\n 'name',\n 'status',\n 'reason',\n 'media_type',\n 'parent_id',\n 'payload',\n 'response',\n 'requested_at',\n 'generated_at',\n 'sent_at',\n ];\n\n /**\n * Get the attributes that should be cast.\n *\n * @return array<string, string>\n */\n protected function casts(): array\n {\n return [\n 'payload' => 'array',\n 'response' => 'array',\n 'requested_at' => 'datetime',\n 'generated_at' => 'datetime',\n 'sent_at' => 'datetime',\n ];\n }\n\n /**\n * Get the automated report that owns this result.\n *\n * @return BelongsTo\n */\n public function report(): BelongsTo\n {\n return $this->belongsTo(AutomatedReport::class, 'report_id')->withTrashed();\n }\n\n /**\n * Get the parent report result.\n *\n * @return BelongsTo\n */\n public function parent(): BelongsTo\n {\n return $this->belongsTo(self::class, 'parent_id');\n }\n\n /**\n * Get the child report results.\n *\n * @return HasMany\n */\n public function children(): HasMany\n {\n return $this->hasMany(self::class, 'parent_id');\n }\n\n /**\n * Get the ID of the automated report result.\n *\n * @return int\n */\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n /**\n * Get the UUID of the automated report result.\n *\n * @return string\n */\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n /**\n * Get the report ID of the automated report result.\n *\n * @return int\n */\n public function getReportId(): int\n {\n return $this->getAttribute('report_id');\n }\n\n /**\n * Get the name of the automated report result.\n *\n * @return ?string\n */\n public function getName(): ?string\n {\n return $this->getAttribute('name');\n }\n\n /**\n * Get the status of the automated report result.\n *\n * @return int\n */\n public function getStatus(): int\n {\n return $this->getAttribute('status');\n }\n\n /**\n * Get the reason of the automated report result.\n *\n * @return int\n */\n public function getReason(): int\n {\n return $this->getAttribute('reason');\n }\n\n /**\n * Get the media type of the automated report result.\n *\n * @return string\n */\n public function getMediaType(): ?string\n {\n return $this->getAttribute('media_type');\n }\n\n /**\n * Get the parent ID of the automated report result.\n *\n * @return int|null\n */\n public function getParentId(): ?int\n {\n return $this->getAttribute('parent_id');\n }\n\n /**\n * Get the payload of the automated report result.\n *\n * @return array|null\n */\n public function getPayload(): ?array\n {\n return $this->getAttribute('payload');\n }\n\n /**\n * Get the response of the automated report result.\n *\n * @return array|null\n */\n public function getResponse(): ?array\n {\n return $this->getAttribute('response');\n }\n\n /**\n * Get the requested at date of the automated report result.\n *\n * @return Carbon|null\n */\n public function getRequestedAt(): ?Carbon\n {\n return $this->getAttribute('requested_at');\n }\n\n /**\n * Get the generated at date of the automated report result.\n *\n * @return Carbon|null\n */\n public function getGeneratedAt(): ?Carbon\n {\n return $this->getAttribute('generated_at');\n }\n\n /**\n * Get the sent at date of the automated report result.\n *\n * @return Carbon|null\n */\n public function getSentAt(): ?Carbon\n {\n return $this->getAttribute('sent_at');\n }\n\n /**\n * Get the created at date of the automated report result.\n *\n * @return Carbon\n */\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n /**\n * Get the updated at date of the automated report result.\n *\n * @return Carbon\n */\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n /**\n * Check if the report result is in requested status.\n *\n * @return bool\n */\n public function isRequested(): bool\n {\n return $this->getStatus() === self::STATUS_REQUESTED;\n }\n\n /**\n * Check if the report result is in generated status.\n *\n * @return bool\n */\n public function isGenerated(): bool\n {\n return $this->getStatus() === self::STATUS_GENERATED;\n }\n\n /**\n * Check if the report result is in sent status.\n *\n * @return bool\n */\n public function isSent(): bool\n {\n return $this->getStatus() === self::STATUS_SENT;\n }\n\n /**\n * Check if the report result is in failed status.\n *\n * @return bool\n */\n public function isFailed(): bool\n {\n return $this->getStatus() === self::STATUS_FAILED;\n }\n\n public function getStatusLabel(): string\n {\n return match ($this->getStatus()) {\n self::STATUS_REQUESTED => 'Requested',\n self::STATUS_GENERATED => 'Generated',\n self::STATUS_SENT => 'Sent',\n self::STATUS_FAILED => 'Failed',\n default => 'Default',\n };\n }\n\n public function getReport(): AutomatedReport\n {\n return $this->getAttribute('report');\n }\n\n public function getFromDate(): ?Carbon\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['from_date'])) {\n return null;\n }\n\n return Carbon::parse($payload['from_date']);\n }\n\n public function getToDate(): ?Carbon\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['to_date'])) {\n return null;\n }\n\n return Carbon::parse($payload['to_date']);\n }\n\n public function getReportType(): ?string\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['report_type'])) {\n return null;\n }\n\n return $payload['report_type'];\n }\n\n public function getGroups(): array\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['group_ids'])) {\n return [];\n }\n\n return $payload['group_ids'];\n }\n\n public function getPdfUrl(): ?string\n {\n $response = $this->getResponse();\n\n return $response['pdf_url'] ?? null;\n }\n\n public function getPodcastAudioUrl(): ?string\n {\n $response = $this->getResponse();\n\n return $response['podcast_audio_url'] ?? null;\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"bounds":{"left":0.42719415,"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.43583778,"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.44680852,"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.4554521,"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.46409574,"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":"In-Editor Results","depth":4,"bounds":{"left":0.47506648,"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":"Tx: Auto","depth":4,"bounds":{"left":0.48603722,"top":0.09896249,"width":0.024268618,"height":0.01915403},"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,"bounds":{"left":0.51263297,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"bounds":{"left":0.52360374,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7084442,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-8255157670987938192
|
5304222162814503980
|
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
8
1
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Carbon;
use Jiminny\Traits\RequiresUUID;
/**
* Jiminny\Models\AutomatedReportResult
*
* @property int $id
* @property string $uuid
* @property int $report_id
* @property string|null $name
* @property int $status
* @property int $reason
* @property string $media_type
* @property int|null $parent_id
* @property array|null $payload
* @property array|null $response
* @property Carbon|null $requested_at
* @property Carbon|null $generated_at
* @property Carbon|null $sent_at
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
* @property-read \Jiminny\Models\AutomatedReport $report
* @property-read AutomatedReportResult|null $parent
* @property-read \Illuminate\Database\Eloquent\Collection<int, AutomatedReportResult> $children
*/
class AutomatedReportResult extends Model
{
use RequiresUUID;
/**
* Status constants
*/
public const int STATUS_DEFAULT = 0;
public const int STATUS_REQUESTED = 1;
public const int STATUS_GENERATED = 2;
public const int STATUS_SENT = 3;
public const int STATUS_FAILED = 4;
/**
* Reason constants
*/
public const int REASON_DEFAULT = 0;
public const int REASON_NOT_ENOUGH_ACTIVITIES = 1;
public const int REASON_PROPHET_API_ERROR = 2;
protected $table = 'automated_report_results';
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'report_id',
'name',
'status',
'reason',
'media_type',
'parent_id',
'payload',
'response',
'requested_at',
'generated_at',
'sent_at',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'payload' => 'array',
'response' => 'array',
'requested_at' => 'datetime',
'generated_at' => 'datetime',
'sent_at' => 'datetime',
];
}
/**
* Get the automated report that owns this result.
*
* @return BelongsTo
*/
public function report(): BelongsTo
{
return $this->belongsTo(AutomatedReport::class, 'report_id')->withTrashed();
}
/**
* Get the parent report result.
*
* @return BelongsTo
*/
public function parent(): BelongsTo
{
return $this->belongsTo(self::class, 'parent_id');
}
/**
* Get the child report results.
*
* @return HasMany
*/
public function children(): HasMany
{
return $this->hasMany(self::class, 'parent_id');
}
/**
* Get the ID of the automated report result.
*
* @return int
*/
public function getId(): int
{
return $this->getAttribute('id');
}
/**
* Get the UUID of the automated report result.
*
* @return string
*/
public function getUuid(): string
{
return $this->getAttribute('id_string');
}
/**
* Get the report ID of the automated report result.
*
* @return int
*/
public function getReportId(): int
{
return $this->getAttribute('report_id');
}
/**
* Get the name of the automated report result.
*
* @return ?string
*/
public function getName(): ?string
{
return $this->getAttribute('name');
}
/**
* Get the status of the automated report result.
*
* @return int
*/
public function getStatus(): int
{
return $this->getAttribute('status');
}
/**
* Get the reason of the automated report result.
*
* @return int
*/
public function getReason(): int
{
return $this->getAttribute('reason');
}
/**
* Get the media type of the automated report result.
*
* @return string
*/
public function getMediaType(): ?string
{
return $this->getAttribute('media_type');
}
/**
* Get the parent ID of the automated report result.
*
* @return int|null
*/
public function getParentId(): ?int
{
return $this->getAttribute('parent_id');
}
/**
* Get the payload of the automated report result.
*
* @return array|null
*/
public function getPayload(): ?array
{
return $this->getAttribute('payload');
}
/**
* Get the response of the automated report result.
*
* @return array|null
*/
public function getResponse(): ?array
{
return $this->getAttribute('response');
}
/**
* Get the requested at date of the automated report result.
*
* @return Carbon|null
*/
public function getRequestedAt(): ?Carbon
{
return $this->getAttribute('requested_at');
}
/**
* Get the generated at date of the automated report result.
*
* @return Carbon|null
*/
public function getGeneratedAt(): ?Carbon
{
return $this->getAttribute('generated_at');
}
/**
* Get the sent at date of the automated report result.
*
* @return Carbon|null
*/
public function getSentAt(): ?Carbon
{
return $this->getAttribute('sent_at');
}
/**
* Get the created at date of the automated report result.
*
* @return Carbon
*/
public function getCreatedAt(): Carbon
{
return $this->getAttribute('created_at');
}
/**
* Get the updated at date of the automated report result.
*
* @return Carbon
*/
public function getUpdatedAt(): Carbon
{
return $this->getAttribute('updated_at');
}
/**
* Check if the report result is in requested status.
*
* @return bool
*/
public function isRequested(): bool
{
return $this->getStatus() === self::STATUS_REQUESTED;
}
/**
* Check if the report result is in generated status.
*
* @return bool
*/
public function isGenerated(): bool
{
return $this->getStatus() === self::STATUS_GENERATED;
}
/**
* Check if the report result is in sent status.
*
* @return bool
*/
public function isSent(): bool
{
return $this->getStatus() === self::STATUS_SENT;
}
/**
* Check if the report result is in failed status.
*
* @return bool
*/
public function isFailed(): bool
{
return $this->getStatus() === self::STATUS_FAILED;
}
public function getStatusLabel(): string
{
return match ($this->getStatus()) {
self::STATUS_REQUESTED => 'Requested',
self::STATUS_GENERATED => 'Generated',
self::STATUS_SENT => 'Sent',
self::STATUS_FAILED => 'Failed',
default => 'Default',
};
}
public function getReport(): AutomatedReport
{
return $this->getAttribute('report');
}
public function getFromDate(): ?Carbon
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['from_date'])) {
return null;
}
return Carbon::parse($payload['from_date']);
}
public function getToDate(): ?Carbon
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['to_date'])) {
return null;
}
return Carbon::parse($payload['to_date']);
}
public function getReportType(): ?string
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['report_type'])) {
return null;
}
return $payload['report_type'];
}
public function getGroups(): array
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['group_ids'])) {
return [];
}
return $payload['group_ids'];
}
public function getPdfUrl(): ?string
{
$response = $this->getResponse();
return $response['pdf_url'] ?? null;
}
public function getPodcastAudioUrl(): ?string
{
$response = $this->getResponse();
return $response['podcast_audio_url'] ?? null;
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
23952
|
1004
|
7
|
2026-05-12T08:31:27.149755+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778574687149_m1.jpg...
|
PhpStorm
|
faVsco.js – console [PROD]
|
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
8
1
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Carbon;
use Jiminny\Traits\RequiresUUID;
/**
* Jiminny\Models\AutomatedReportResult
*
* @property int $id
* @property string $uuid
* @property int $report_id
* @property string|null $name
* @property int $status
* @property int $reason
* @property string $media_type
* @property int|null $parent_id
* @property array|null $payload
* @property array|null $response
* @property Carbon|null $requested_at
* @property Carbon|null $generated_at
* @property Carbon|null $sent_at
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
* @property-read \Jiminny\Models\AutomatedReport $report
* @property-read AutomatedReportResult|null $parent
* @property-read \Illuminate\Database\Eloquent\Collection<int, AutomatedReportResult> $children
*/
class AutomatedReportResult extends Model
{
use RequiresUUID;
/**
* Status constants
*/
public const int STATUS_DEFAULT = 0;
public const int STATUS_REQUESTED = 1;
public const int STATUS_GENERATED = 2;
public const int STATUS_SENT = 3;
public const int STATUS_FAILED = 4;
/**
* Reason constants
*/
public const int REASON_DEFAULT = 0;
public const int REASON_NOT_ENOUGH_ACTIVITIES = 1;
public const int REASON_PROPHET_API_ERROR = 2;
protected $table = 'automated_report_results';
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'report_id',
'name',
'status',
'reason',
'media_type',
'parent_id',
'payload',
'response',
'requested_at',
'generated_at',
'sent_at',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'payload' => 'array',
'response' => 'array',
'requested_at' => 'datetime',
'generated_at' => 'datetime',
'sent_at' => 'datetime',
];
}
/**
* Get the automated report that owns this result.
*
* @return BelongsTo
*/
public function report(): BelongsTo
{
return $this->belongsTo(AutomatedReport::class, 'report_id')->withTrashed();
}
/**
* Get the parent report result.
*
* @return BelongsTo
*/
public function parent(): BelongsTo
{
return $this->belongsTo(self::class, 'parent_id');
}
/**
* Get the child report results.
*
* @return HasMany
*/
public function children(): HasMany
{
return $this->hasMany(self::class, 'parent_id');
}
/**
* Get the ID of the automated report result.
*
* @return int
*/
public function getId(): int
{
return $this->getAttribute('id');
}
/**
* Get the UUID of the automated report result.
*
* @return string
*/
public function getUuid(): string
{
return $this->getAttribute('id_string');
}
/**
* Get the report ID of the automated report result.
*
* @return int
*/
public function getReportId(): int
{
return $this->getAttribute('report_id');
}
/**
* Get the name of the automated report result.
*
* @return ?string
*/
public function getName(): ?string
{
return $this->getAttribute('name');
}
/**
* Get the status of the automated report result.
*
* @return int
*/
public function getStatus(): int
{
return $this->getAttribute('status');
}
/**
* Get the reason of the automated report result.
*
* @return int
*/
public function getReason(): int
{
return $this->getAttribute('reason');
}
/**
* Get the media type of the automated report result.
*
* @return string
*/
public function getMediaType(): ?string
{
return $this->getAttribute('media_type');
}
/**
* Get the parent ID of the automated report result.
*
* @return int|null
*/
public function getParentId(): ?int
{
return $this->getAttribute('parent_id');
}
/**
* Get the payload of the automated report result.
*
* @return array|null
*/
public function getPayload(): ?array
{
return $this->getAttribute('payload');
}
/**
* Get the response of the automated report result.
*
* @return array|null
*/
public function getResponse(): ?array
{
return $this->getAttribute('response');
}
/**
* Get the requested at date of the automated report result.
*
* @return Carbon|null
*/
public function getRequestedAt(): ?Carbon
{
return $this->getAttribute('requested_at');
}
/**
* Get the generated at date of the automated report result.
*
* @return Carbon|null
*/
public function getGeneratedAt(): ?Carbon
{
return $this->getAttribute('generated_at');
}
/**
* Get the sent at date of the automated report result.
*
* @return Carbon|null
*/
public function getSentAt(): ?Carbon
{
return $this->getAttribute('sent_at');
}
/**
* Get the created at date of the automated report result.
*
* @return Carbon
*/
public function getCreatedAt(): Carbon
{
return $this->getAttribute('created_at');
}
/**
* Get the updated at date of the automated report result.
*
* @return Carbon
*/
public function getUpdatedAt(): Carbon
{
return $this->getAttribute('updated_at');
}
/**
* Check if the report result is in requested status.
*
* @return bool
*/
public function isRequested(): bool
{
return $this->getStatus() === self::STATUS_REQUESTED;
}
/**
* Check if the report result is in generated status.
*
* @return bool
*/
public function isGenerated(): bool
{
return $this->getStatus() === self::STATUS_GENERATED;
}
/**
* Check if the report result is in sent status.
*
* @return bool
*/
public function isSent(): bool
{
return $this->getStatus() === self::STATUS_SENT;
}
/**
* Check if the report result is in failed status.
*
* @return bool
*/
public function isFailed(): bool
{
return $this->getStatus() === self::STATUS_FAILED;
}
public function getStatusLabel(): string
{
return match ($this->getStatus()) {
self::STATUS_REQUESTED => 'Requested',
self::STATUS_GENERATED => 'Generated',
self::STATUS_SENT => 'Sent',
self::STATUS_FAILED => 'Failed',
default => 'Default',
};
}
public function getReport(): AutomatedReport
{
return $this->getAttribute('report');
}
public function getFromDate(): ?Carbon
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['from_date'])) {
return null;
}
return Carbon::parse($payload['from_date']);
}
public function getToDate(): ?Carbon
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['to_date'])) {
return null;
}
return Carbon::parse($payload['to_date']);
}
public function getReportType(): ?string
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['report_type'])) {
return null;
}
return $payload['report_type'];
}
public function getGroups(): array
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['group_ids'])) {
return [];
}
return $payload['group_ids'];
}
public function getPdfUrl(): ?string
{
$response = $this->getResponse();
return $response['pdf_url'] ?? null;
}
public function getPodcastAudioUrl(): ?string
{
$response = $this->getResponse();
return $response['podcast_audio_url'] ?? null;
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny...
|
[{"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":"AXStaticText","text":"8","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","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\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Support\\Carbon;\nuse Jiminny\\Traits\\RequiresUUID;\n\n/**\n * Jiminny\\Models\\AutomatedReportResult\n *\n * @property int $id\n * @property string $uuid\n * @property int $report_id\n * @property string|null $name\n * @property int $status\n * @property int $reason\n * @property string $media_type\n * @property int|null $parent_id\n * @property array|null $payload\n * @property array|null $response\n * @property Carbon|null $requested_at\n * @property Carbon|null $generated_at\n * @property Carbon|null $sent_at\n * @property Carbon|null $created_at\n * @property Carbon|null $updated_at\n * @property-read \\Jiminny\\Models\\AutomatedReport $report\n * @property-read AutomatedReportResult|null $parent\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, AutomatedReportResult> $children\n */\nclass AutomatedReportResult extends Model\n{\n use RequiresUUID;\n\n /**\n * Status constants\n */\n public const int STATUS_DEFAULT = 0;\n public const int STATUS_REQUESTED = 1;\n public const int STATUS_GENERATED = 2;\n public const int STATUS_SENT = 3;\n public const int STATUS_FAILED = 4;\n\n /**\n * Reason constants\n */\n public const int REASON_DEFAULT = 0;\n public const int REASON_NOT_ENOUGH_ACTIVITIES = 1;\n public const int REASON_PROPHET_API_ERROR = 2;\n\n protected $table = 'automated_report_results';\n\n /**\n * The attributes that are mass assignable.\n *\n * @var array<int, string>\n */\n protected $fillable = [\n 'report_id',\n 'name',\n 'status',\n 'reason',\n 'media_type',\n 'parent_id',\n 'payload',\n 'response',\n 'requested_at',\n 'generated_at',\n 'sent_at',\n ];\n\n /**\n * Get the attributes that should be cast.\n *\n * @return array<string, string>\n */\n protected function casts(): array\n {\n return [\n 'payload' => 'array',\n 'response' => 'array',\n 'requested_at' => 'datetime',\n 'generated_at' => 'datetime',\n 'sent_at' => 'datetime',\n ];\n }\n\n /**\n * Get the automated report that owns this result.\n *\n * @return BelongsTo\n */\n public function report(): BelongsTo\n {\n return $this->belongsTo(AutomatedReport::class, 'report_id')->withTrashed();\n }\n\n /**\n * Get the parent report result.\n *\n * @return BelongsTo\n */\n public function parent(): BelongsTo\n {\n return $this->belongsTo(self::class, 'parent_id');\n }\n\n /**\n * Get the child report results.\n *\n * @return HasMany\n */\n public function children(): HasMany\n {\n return $this->hasMany(self::class, 'parent_id');\n }\n\n /**\n * Get the ID of the automated report result.\n *\n * @return int\n */\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n /**\n * Get the UUID of the automated report result.\n *\n * @return string\n */\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n /**\n * Get the report ID of the automated report result.\n *\n * @return int\n */\n public function getReportId(): int\n {\n return $this->getAttribute('report_id');\n }\n\n /**\n * Get the name of the automated report result.\n *\n * @return ?string\n */\n public function getName(): ?string\n {\n return $this->getAttribute('name');\n }\n\n /**\n * Get the status of the automated report result.\n *\n * @return int\n */\n public function getStatus(): int\n {\n return $this->getAttribute('status');\n }\n\n /**\n * Get the reason of the automated report result.\n *\n * @return int\n */\n public function getReason(): int\n {\n return $this->getAttribute('reason');\n }\n\n /**\n * Get the media type of the automated report result.\n *\n * @return string\n */\n public function getMediaType(): ?string\n {\n return $this->getAttribute('media_type');\n }\n\n /**\n * Get the parent ID of the automated report result.\n *\n * @return int|null\n */\n public function getParentId(): ?int\n {\n return $this->getAttribute('parent_id');\n }\n\n /**\n * Get the payload of the automated report result.\n *\n * @return array|null\n */\n public function getPayload(): ?array\n {\n return $this->getAttribute('payload');\n }\n\n /**\n * Get the response of the automated report result.\n *\n * @return array|null\n */\n public function getResponse(): ?array\n {\n return $this->getAttribute('response');\n }\n\n /**\n * Get the requested at date of the automated report result.\n *\n * @return Carbon|null\n */\n public function getRequestedAt(): ?Carbon\n {\n return $this->getAttribute('requested_at');\n }\n\n /**\n * Get the generated at date of the automated report result.\n *\n * @return Carbon|null\n */\n public function getGeneratedAt(): ?Carbon\n {\n return $this->getAttribute('generated_at');\n }\n\n /**\n * Get the sent at date of the automated report result.\n *\n * @return Carbon|null\n */\n public function getSentAt(): ?Carbon\n {\n return $this->getAttribute('sent_at');\n }\n\n /**\n * Get the created at date of the automated report result.\n *\n * @return Carbon\n */\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n /**\n * Get the updated at date of the automated report result.\n *\n * @return Carbon\n */\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n /**\n * Check if the report result is in requested status.\n *\n * @return bool\n */\n public function isRequested(): bool\n {\n return $this->getStatus() === self::STATUS_REQUESTED;\n }\n\n /**\n * Check if the report result is in generated status.\n *\n * @return bool\n */\n public function isGenerated(): bool\n {\n return $this->getStatus() === self::STATUS_GENERATED;\n }\n\n /**\n * Check if the report result is in sent status.\n *\n * @return bool\n */\n public function isSent(): bool\n {\n return $this->getStatus() === self::STATUS_SENT;\n }\n\n /**\n * Check if the report result is in failed status.\n *\n * @return bool\n */\n public function isFailed(): bool\n {\n return $this->getStatus() === self::STATUS_FAILED;\n }\n\n public function getStatusLabel(): string\n {\n return match ($this->getStatus()) {\n self::STATUS_REQUESTED => 'Requested',\n self::STATUS_GENERATED => 'Generated',\n self::STATUS_SENT => 'Sent',\n self::STATUS_FAILED => 'Failed',\n default => 'Default',\n };\n }\n\n public function getReport(): AutomatedReport\n {\n return $this->getAttribute('report');\n }\n\n public function getFromDate(): ?Carbon\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['from_date'])) {\n return null;\n }\n\n return Carbon::parse($payload['from_date']);\n }\n\n public function getToDate(): ?Carbon\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['to_date'])) {\n return null;\n }\n\n return Carbon::parse($payload['to_date']);\n }\n\n public function getReportType(): ?string\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['report_type'])) {\n return null;\n }\n\n return $payload['report_type'];\n }\n\n public function getGroups(): array\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['group_ids'])) {\n return [];\n }\n\n return $payload['group_ids'];\n }\n\n public function getPdfUrl(): ?string\n {\n $response = $this->getResponse();\n\n return $response['pdf_url'] ?? null;\n }\n\n public function getPodcastAudioUrl(): ?string\n {\n $response = $this->getResponse();\n\n return $response['podcast_audio_url'] ?? null;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Support\\Carbon;\nuse Jiminny\\Traits\\RequiresUUID;\n\n/**\n * Jiminny\\Models\\AutomatedReportResult\n *\n * @property int $id\n * @property string $uuid\n * @property int $report_id\n * @property string|null $name\n * @property int $status\n * @property int $reason\n * @property string $media_type\n * @property int|null $parent_id\n * @property array|null $payload\n * @property array|null $response\n * @property Carbon|null $requested_at\n * @property Carbon|null $generated_at\n * @property Carbon|null $sent_at\n * @property Carbon|null $created_at\n * @property Carbon|null $updated_at\n * @property-read \\Jiminny\\Models\\AutomatedReport $report\n * @property-read AutomatedReportResult|null $parent\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, AutomatedReportResult> $children\n */\nclass AutomatedReportResult extends Model\n{\n use RequiresUUID;\n\n /**\n * Status constants\n */\n public const int STATUS_DEFAULT = 0;\n public const int STATUS_REQUESTED = 1;\n public const int STATUS_GENERATED = 2;\n public const int STATUS_SENT = 3;\n public const int STATUS_FAILED = 4;\n\n /**\n * Reason constants\n */\n public const int REASON_DEFAULT = 0;\n public const int REASON_NOT_ENOUGH_ACTIVITIES = 1;\n public const int REASON_PROPHET_API_ERROR = 2;\n\n protected $table = 'automated_report_results';\n\n /**\n * The attributes that are mass assignable.\n *\n * @var array<int, string>\n */\n protected $fillable = [\n 'report_id',\n 'name',\n 'status',\n 'reason',\n 'media_type',\n 'parent_id',\n 'payload',\n 'response',\n 'requested_at',\n 'generated_at',\n 'sent_at',\n ];\n\n /**\n * Get the attributes that should be cast.\n *\n * @return array<string, string>\n */\n protected function casts(): array\n {\n return [\n 'payload' => 'array',\n 'response' => 'array',\n 'requested_at' => 'datetime',\n 'generated_at' => 'datetime',\n 'sent_at' => 'datetime',\n ];\n }\n\n /**\n * Get the automated report that owns this result.\n *\n * @return BelongsTo\n */\n public function report(): BelongsTo\n {\n return $this->belongsTo(AutomatedReport::class, 'report_id')->withTrashed();\n }\n\n /**\n * Get the parent report result.\n *\n * @return BelongsTo\n */\n public function parent(): BelongsTo\n {\n return $this->belongsTo(self::class, 'parent_id');\n }\n\n /**\n * Get the child report results.\n *\n * @return HasMany\n */\n public function children(): HasMany\n {\n return $this->hasMany(self::class, 'parent_id');\n }\n\n /**\n * Get the ID of the automated report result.\n *\n * @return int\n */\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n /**\n * Get the UUID of the automated report result.\n *\n * @return string\n */\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n /**\n * Get the report ID of the automated report result.\n *\n * @return int\n */\n public function getReportId(): int\n {\n return $this->getAttribute('report_id');\n }\n\n /**\n * Get the name of the automated report result.\n *\n * @return ?string\n */\n public function getName(): ?string\n {\n return $this->getAttribute('name');\n }\n\n /**\n * Get the status of the automated report result.\n *\n * @return int\n */\n public function getStatus(): int\n {\n return $this->getAttribute('status');\n }\n\n /**\n * Get the reason of the automated report result.\n *\n * @return int\n */\n public function getReason(): int\n {\n return $this->getAttribute('reason');\n }\n\n /**\n * Get the media type of the automated report result.\n *\n * @return string\n */\n public function getMediaType(): ?string\n {\n return $this->getAttribute('media_type');\n }\n\n /**\n * Get the parent ID of the automated report result.\n *\n * @return int|null\n */\n public function getParentId(): ?int\n {\n return $this->getAttribute('parent_id');\n }\n\n /**\n * Get the payload of the automated report result.\n *\n * @return array|null\n */\n public function getPayload(): ?array\n {\n return $this->getAttribute('payload');\n }\n\n /**\n * Get the response of the automated report result.\n *\n * @return array|null\n */\n public function getResponse(): ?array\n {\n return $this->getAttribute('response');\n }\n\n /**\n * Get the requested at date of the automated report result.\n *\n * @return Carbon|null\n */\n public function getRequestedAt(): ?Carbon\n {\n return $this->getAttribute('requested_at');\n }\n\n /**\n * Get the generated at date of the automated report result.\n *\n * @return Carbon|null\n */\n public function getGeneratedAt(): ?Carbon\n {\n return $this->getAttribute('generated_at');\n }\n\n /**\n * Get the sent at date of the automated report result.\n *\n * @return Carbon|null\n */\n public function getSentAt(): ?Carbon\n {\n return $this->getAttribute('sent_at');\n }\n\n /**\n * Get the created at date of the automated report result.\n *\n * @return Carbon\n */\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n /**\n * Get the updated at date of the automated report result.\n *\n * @return Carbon\n */\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n /**\n * Check if the report result is in requested status.\n *\n * @return bool\n */\n public function isRequested(): bool\n {\n return $this->getStatus() === self::STATUS_REQUESTED;\n }\n\n /**\n * Check if the report result is in generated status.\n *\n * @return bool\n */\n public function isGenerated(): bool\n {\n return $this->getStatus() === self::STATUS_GENERATED;\n }\n\n /**\n * Check if the report result is in sent status.\n *\n * @return bool\n */\n public function isSent(): bool\n {\n return $this->getStatus() === self::STATUS_SENT;\n }\n\n /**\n * Check if the report result is in failed status.\n *\n * @return bool\n */\n public function isFailed(): bool\n {\n return $this->getStatus() === self::STATUS_FAILED;\n }\n\n public function getStatusLabel(): string\n {\n return match ($this->getStatus()) {\n self::STATUS_REQUESTED => 'Requested',\n self::STATUS_GENERATED => 'Generated',\n self::STATUS_SENT => 'Sent',\n self::STATUS_FAILED => 'Failed',\n default => 'Default',\n };\n }\n\n public function getReport(): AutomatedReport\n {\n return $this->getAttribute('report');\n }\n\n public function getFromDate(): ?Carbon\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['from_date'])) {\n return null;\n }\n\n return Carbon::parse($payload['from_date']);\n }\n\n public function getToDate(): ?Carbon\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['to_date'])) {\n return null;\n }\n\n return Carbon::parse($payload['to_date']);\n }\n\n public function getReportType(): ?string\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['report_type'])) {\n return null;\n }\n\n return $payload['report_type'];\n }\n\n public function getGroups(): array\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['group_ids'])) {\n return [];\n }\n\n return $payload['group_ids'];\n }\n\n public function getPdfUrl(): ?string\n {\n $response = $this->getResponse();\n\n return $response['pdf_url'] ?? null;\n }\n\n public function getPodcastAudioUrl(): ?string\n {\n $response = $this->getResponse();\n\n return $response['podcast_audio_url'] ?? null;\n }\n}","role_description":"text entry area","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}]...
|
-8255157670987938192
|
5304222162814503980
|
app_switch
|
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
8
1
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Carbon;
use Jiminny\Traits\RequiresUUID;
/**
* Jiminny\Models\AutomatedReportResult
*
* @property int $id
* @property string $uuid
* @property int $report_id
* @property string|null $name
* @property int $status
* @property int $reason
* @property string $media_type
* @property int|null $parent_id
* @property array|null $payload
* @property array|null $response
* @property Carbon|null $requested_at
* @property Carbon|null $generated_at
* @property Carbon|null $sent_at
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
* @property-read \Jiminny\Models\AutomatedReport $report
* @property-read AutomatedReportResult|null $parent
* @property-read \Illuminate\Database\Eloquent\Collection<int, AutomatedReportResult> $children
*/
class AutomatedReportResult extends Model
{
use RequiresUUID;
/**
* Status constants
*/
public const int STATUS_DEFAULT = 0;
public const int STATUS_REQUESTED = 1;
public const int STATUS_GENERATED = 2;
public const int STATUS_SENT = 3;
public const int STATUS_FAILED = 4;
/**
* Reason constants
*/
public const int REASON_DEFAULT = 0;
public const int REASON_NOT_ENOUGH_ACTIVITIES = 1;
public const int REASON_PROPHET_API_ERROR = 2;
protected $table = 'automated_report_results';
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'report_id',
'name',
'status',
'reason',
'media_type',
'parent_id',
'payload',
'response',
'requested_at',
'generated_at',
'sent_at',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'payload' => 'array',
'response' => 'array',
'requested_at' => 'datetime',
'generated_at' => 'datetime',
'sent_at' => 'datetime',
];
}
/**
* Get the automated report that owns this result.
*
* @return BelongsTo
*/
public function report(): BelongsTo
{
return $this->belongsTo(AutomatedReport::class, 'report_id')->withTrashed();
}
/**
* Get the parent report result.
*
* @return BelongsTo
*/
public function parent(): BelongsTo
{
return $this->belongsTo(self::class, 'parent_id');
}
/**
* Get the child report results.
*
* @return HasMany
*/
public function children(): HasMany
{
return $this->hasMany(self::class, 'parent_id');
}
/**
* Get the ID of the automated report result.
*
* @return int
*/
public function getId(): int
{
return $this->getAttribute('id');
}
/**
* Get the UUID of the automated report result.
*
* @return string
*/
public function getUuid(): string
{
return $this->getAttribute('id_string');
}
/**
* Get the report ID of the automated report result.
*
* @return int
*/
public function getReportId(): int
{
return $this->getAttribute('report_id');
}
/**
* Get the name of the automated report result.
*
* @return ?string
*/
public function getName(): ?string
{
return $this->getAttribute('name');
}
/**
* Get the status of the automated report result.
*
* @return int
*/
public function getStatus(): int
{
return $this->getAttribute('status');
}
/**
* Get the reason of the automated report result.
*
* @return int
*/
public function getReason(): int
{
return $this->getAttribute('reason');
}
/**
* Get the media type of the automated report result.
*
* @return string
*/
public function getMediaType(): ?string
{
return $this->getAttribute('media_type');
}
/**
* Get the parent ID of the automated report result.
*
* @return int|null
*/
public function getParentId(): ?int
{
return $this->getAttribute('parent_id');
}
/**
* Get the payload of the automated report result.
*
* @return array|null
*/
public function getPayload(): ?array
{
return $this->getAttribute('payload');
}
/**
* Get the response of the automated report result.
*
* @return array|null
*/
public function getResponse(): ?array
{
return $this->getAttribute('response');
}
/**
* Get the requested at date of the automated report result.
*
* @return Carbon|null
*/
public function getRequestedAt(): ?Carbon
{
return $this->getAttribute('requested_at');
}
/**
* Get the generated at date of the automated report result.
*
* @return Carbon|null
*/
public function getGeneratedAt(): ?Carbon
{
return $this->getAttribute('generated_at');
}
/**
* Get the sent at date of the automated report result.
*
* @return Carbon|null
*/
public function getSentAt(): ?Carbon
{
return $this->getAttribute('sent_at');
}
/**
* Get the created at date of the automated report result.
*
* @return Carbon
*/
public function getCreatedAt(): Carbon
{
return $this->getAttribute('created_at');
}
/**
* Get the updated at date of the automated report result.
*
* @return Carbon
*/
public function getUpdatedAt(): Carbon
{
return $this->getAttribute('updated_at');
}
/**
* Check if the report result is in requested status.
*
* @return bool
*/
public function isRequested(): bool
{
return $this->getStatus() === self::STATUS_REQUESTED;
}
/**
* Check if the report result is in generated status.
*
* @return bool
*/
public function isGenerated(): bool
{
return $this->getStatus() === self::STATUS_GENERATED;
}
/**
* Check if the report result is in sent status.
*
* @return bool
*/
public function isSent(): bool
{
return $this->getStatus() === self::STATUS_SENT;
}
/**
* Check if the report result is in failed status.
*
* @return bool
*/
public function isFailed(): bool
{
return $this->getStatus() === self::STATUS_FAILED;
}
public function getStatusLabel(): string
{
return match ($this->getStatus()) {
self::STATUS_REQUESTED => 'Requested',
self::STATUS_GENERATED => 'Generated',
self::STATUS_SENT => 'Sent',
self::STATUS_FAILED => 'Failed',
default => 'Default',
};
}
public function getReport(): AutomatedReport
{
return $this->getAttribute('report');
}
public function getFromDate(): ?Carbon
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['from_date'])) {
return null;
}
return Carbon::parse($payload['from_date']);
}
public function getToDate(): ?Carbon
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['to_date'])) {
return null;
}
return Carbon::parse($payload['to_date']);
}
public function getReportType(): ?string
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['report_type'])) {
return null;
}
return $payload['report_type'];
}
public function getGroups(): array
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['group_ids'])) {
return [];
}
return $payload['group_ids'];
}
public function getPdfUrl(): ?string
{
$response = $this->getResponse();
return $response['pdf_url'] ?? null;
}
public function getPodcastAudioUrl(): ?string
{
$response = $this->getResponse();
return $response['podcast_audio_url'] ?? null;
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
23973
|
1005
|
14
|
2026-05-12T08:31:58.831859+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778574718831_m2.jpg...
|
PhpStorm
|
faVsco.js – console [PROD]
|
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
8
1
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Carbon;
use Jiminny\Traits\RequiresUUID;
/**
* Jiminny\Models\AutomatedReportResult
*
* @property int $id
* @property string $uuid
* @property int $report_id
* @property string|null $name
* @property int $status
* @property int $reason
* @property string $media_type
* @property int|null $parent_id
* @property array|null $payload
* @property array|null $response
* @property Carbon|null $requested_at
* @property Carbon|null $generated_at
* @property Carbon|null $sent_at
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
* @property-read \Jiminny\Models\AutomatedReport $report
* @property-read AutomatedReportResult|null $parent
* @property-read \Illuminate\Database\Eloquent\Collection<int, AutomatedReportResult> $children
*/
class AutomatedReportResult extends Model
{
use RequiresUUID;
/**
* Status constants
*/
public const int STATUS_DEFAULT = 0;
public const int STATUS_REQUESTED = 1;
public const int STATUS_GENERATED = 2;
public const int STATUS_SENT = 3;
public const int STATUS_FAILED = 4;
/**
* Reason constants
*/
public const int REASON_DEFAULT = 0;
public const int REASON_NOT_ENOUGH_ACTIVITIES = 1;
public const int REASON_PROPHET_API_ERROR = 2;
protected $table = 'automated_report_results';
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'report_id',
'name',
'status',
'reason',
'media_type',
'parent_id',
'payload',
'response',
'requested_at',
'generated_at',
'sent_at',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'payload' => 'array',
'response' => 'array',
'requested_at' => 'datetime',
'generated_at' => 'datetime',
'sent_at' => 'datetime',
];
}
/**
* Get the automated report that owns this result.
*
* @return BelongsTo
*/
public function report(): BelongsTo
{
return $this->belongsTo(AutomatedReport::class, 'report_id')->withTrashed();
}
/**
* Get the parent report result.
*
* @return BelongsTo
*/
public function parent(): BelongsTo
{
return $this->belongsTo(self::class, 'parent_id');
}
/**
* Get the child report results.
*
* @return HasMany
*/
public function children(): HasMany
{
return $this->hasMany(self::class, 'parent_id');
}
/**
* Get the ID of the automated report result.
*
* @return int
*/
public function getId(): int
{
return $this->getAttribute('id');
}
/**
* Get the UUID of the automated report result.
*
* @return string
*/
public function getUuid(): string
{
return $this->getAttribute('id_string');
}
/**
* Get the report ID of the automated report result.
*
* @return int
*/
public function getReportId(): int
{
return $this->getAttribute('report_id');
}
/**
* Get the name of the automated report result.
*
* @return ?string
*/
public function getName(): ?string
{
return $this->getAttribute('name');
}
/**
* Get the status of the automated report result.
*
* @return int
*/
public function getStatus(): int
{
return $this->getAttribute('status');
}
/**
* Get the reason of the automated report result.
*
* @return int
*/
public function getReason(): int
{
return $this->getAttribute('reason');
}
/**
* Get the media type of the automated report result.
*
* @return string
*/
public function getMediaType(): ?string
{
return $this->getAttribute('media_type');
}
/**
* Get the parent ID of the automated report result.
*
* @return int|null
*/
public function getParentId(): ?int
{
return $this->getAttribute('parent_id');
}
/**
* Get the payload of the automated report result.
*
* @return array|null
*/
public function getPayload(): ?array
{
return $this->getAttribute('payload');
}
/**
* Get the response of the automated report result.
*
* @return array|null
*/
public function getResponse(): ?array
{
return $this->getAttribute('response');
}
/**
* Get the requested at date of the automated report result.
*
* @return Carbon|null
*/
public function getRequestedAt(): ?Carbon
{
return $this->getAttribute('requested_at');
}
/**
* Get the generated at date of the automated report result.
*
* @return Carbon|null
*/
public function getGeneratedAt(): ?Carbon
{
return $this->getAttribute('generated_at');
}
/**
* Get the sent at date of the automated report result.
*
* @return Carbon|null
*/
public function getSentAt(): ?Carbon
{
return $this->getAttribute('sent_at');
}
/**
* Get the created at date of the automated report result.
*
* @return Carbon
*/
public function getCreatedAt(): Carbon
{
return $this->getAttribute('created_at');
}
/**
* Get the updated at date of the automated report result.
*
* @return Carbon
*/
public function getUpdatedAt(): Carbon
{
return $this->getAttribute('updated_at');
}
/**
* Check if the report result is in requested status.
*
* @return bool
*/
public function isRequested(): bool
{
return $this->getStatus() === self::STATUS_REQUESTED;
}
/**
* Check if the report result is in generated status.
*
* @return bool
*/
public function isGenerated(): bool
{
return $this->getStatus() === self::STATUS_GENERATED;
}
/**
* Check if the report result is in sent status.
*
* @return bool
*/
public function isSent(): bool
{
return $this->getStatus() === self::STATUS_SENT;
}
/**
* Check if the report result is in failed status.
*
* @return bool
*/
public function isFailed(): bool
{
return $this->getStatus() === self::STATUS_FAILED;
}
public function getStatusLabel(): string
{
return match ($this->getStatus()) {
self::STATUS_REQUESTED => 'Requested',
self::STATUS_GENERATED => 'Generated',
self::STATUS_SENT => 'Sent',
self::STATUS_FAILED => 'Failed',
default => 'Default',
};
}
public function getReport(): AutomatedReport
{
return $this->getAttribute('report');
}
public function getFromDate(): ?Carbon
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['from_date'])) {
return null;
}
return Carbon::parse($payload['from_date']);
}
public function getToDate(): ?Carbon
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['to_date'])) {
return null;
}
return Carbon::parse($payload['to_date']);
}
public function getReportType(): ?string
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['report_type'])) {
return null;
}
return $payload['report_type'];
}
public function getGroups(): array
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['group_ids'])) {
return [];
}
return $payload['group_ids'];
}
public function getPdfUrl(): ?string
{
$response = $this->getResponse();
return $response['pdf_url'] ?? null;
}
public function getPodcastAudioUrl(): ?string
{
$response = $this->getResponse();
return $response['podcast_audio_url'] ?? null;
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny...
|
[{"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":"AXStaticText","text":"8","depth":4,"bounds":{"left":0.38297874,"top":0.10055866,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.3929521,"top":0.10055866,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.40226063,"top":0.10055866,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.4112367,"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.41855052,"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":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Support\\Carbon;\nuse Jiminny\\Traits\\RequiresUUID;\n\n/**\n * Jiminny\\Models\\AutomatedReportResult\n *\n * @property int $id\n * @property string $uuid\n * @property int $report_id\n * @property string|null $name\n * @property int $status\n * @property int $reason\n * @property string $media_type\n * @property int|null $parent_id\n * @property array|null $payload\n * @property array|null $response\n * @property Carbon|null $requested_at\n * @property Carbon|null $generated_at\n * @property Carbon|null $sent_at\n * @property Carbon|null $created_at\n * @property Carbon|null $updated_at\n * @property-read \\Jiminny\\Models\\AutomatedReport $report\n * @property-read AutomatedReportResult|null $parent\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, AutomatedReportResult> $children\n */\nclass AutomatedReportResult extends Model\n{\n use RequiresUUID;\n\n /**\n * Status constants\n */\n public const int STATUS_DEFAULT = 0;\n public const int STATUS_REQUESTED = 1;\n public const int STATUS_GENERATED = 2;\n public const int STATUS_SENT = 3;\n public const int STATUS_FAILED = 4;\n\n /**\n * Reason constants\n */\n public const int REASON_DEFAULT = 0;\n public const int REASON_NOT_ENOUGH_ACTIVITIES = 1;\n public const int REASON_PROPHET_API_ERROR = 2;\n\n protected $table = 'automated_report_results';\n\n /**\n * The attributes that are mass assignable.\n *\n * @var array<int, string>\n */\n protected $fillable = [\n 'report_id',\n 'name',\n 'status',\n 'reason',\n 'media_type',\n 'parent_id',\n 'payload',\n 'response',\n 'requested_at',\n 'generated_at',\n 'sent_at',\n ];\n\n /**\n * Get the attributes that should be cast.\n *\n * @return array<string, string>\n */\n protected function casts(): array\n {\n return [\n 'payload' => 'array',\n 'response' => 'array',\n 'requested_at' => 'datetime',\n 'generated_at' => 'datetime',\n 'sent_at' => 'datetime',\n ];\n }\n\n /**\n * Get the automated report that owns this result.\n *\n * @return BelongsTo\n */\n public function report(): BelongsTo\n {\n return $this->belongsTo(AutomatedReport::class, 'report_id')->withTrashed();\n }\n\n /**\n * Get the parent report result.\n *\n * @return BelongsTo\n */\n public function parent(): BelongsTo\n {\n return $this->belongsTo(self::class, 'parent_id');\n }\n\n /**\n * Get the child report results.\n *\n * @return HasMany\n */\n public function children(): HasMany\n {\n return $this->hasMany(self::class, 'parent_id');\n }\n\n /**\n * Get the ID of the automated report result.\n *\n * @return int\n */\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n /**\n * Get the UUID of the automated report result.\n *\n * @return string\n */\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n /**\n * Get the report ID of the automated report result.\n *\n * @return int\n */\n public function getReportId(): int\n {\n return $this->getAttribute('report_id');\n }\n\n /**\n * Get the name of the automated report result.\n *\n * @return ?string\n */\n public function getName(): ?string\n {\n return $this->getAttribute('name');\n }\n\n /**\n * Get the status of the automated report result.\n *\n * @return int\n */\n public function getStatus(): int\n {\n return $this->getAttribute('status');\n }\n\n /**\n * Get the reason of the automated report result.\n *\n * @return int\n */\n public function getReason(): int\n {\n return $this->getAttribute('reason');\n }\n\n /**\n * Get the media type of the automated report result.\n *\n * @return string\n */\n public function getMediaType(): ?string\n {\n return $this->getAttribute('media_type');\n }\n\n /**\n * Get the parent ID of the automated report result.\n *\n * @return int|null\n */\n public function getParentId(): ?int\n {\n return $this->getAttribute('parent_id');\n }\n\n /**\n * Get the payload of the automated report result.\n *\n * @return array|null\n */\n public function getPayload(): ?array\n {\n return $this->getAttribute('payload');\n }\n\n /**\n * Get the response of the automated report result.\n *\n * @return array|null\n */\n public function getResponse(): ?array\n {\n return $this->getAttribute('response');\n }\n\n /**\n * Get the requested at date of the automated report result.\n *\n * @return Carbon|null\n */\n public function getRequestedAt(): ?Carbon\n {\n return $this->getAttribute('requested_at');\n }\n\n /**\n * Get the generated at date of the automated report result.\n *\n * @return Carbon|null\n */\n public function getGeneratedAt(): ?Carbon\n {\n return $this->getAttribute('generated_at');\n }\n\n /**\n * Get the sent at date of the automated report result.\n *\n * @return Carbon|null\n */\n public function getSentAt(): ?Carbon\n {\n return $this->getAttribute('sent_at');\n }\n\n /**\n * Get the created at date of the automated report result.\n *\n * @return Carbon\n */\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n /**\n * Get the updated at date of the automated report result.\n *\n * @return Carbon\n */\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n /**\n * Check if the report result is in requested status.\n *\n * @return bool\n */\n public function isRequested(): bool\n {\n return $this->getStatus() === self::STATUS_REQUESTED;\n }\n\n /**\n * Check if the report result is in generated status.\n *\n * @return bool\n */\n public function isGenerated(): bool\n {\n return $this->getStatus() === self::STATUS_GENERATED;\n }\n\n /**\n * Check if the report result is in sent status.\n *\n * @return bool\n */\n public function isSent(): bool\n {\n return $this->getStatus() === self::STATUS_SENT;\n }\n\n /**\n * Check if the report result is in failed status.\n *\n * @return bool\n */\n public function isFailed(): bool\n {\n return $this->getStatus() === self::STATUS_FAILED;\n }\n\n public function getStatusLabel(): string\n {\n return match ($this->getStatus()) {\n self::STATUS_REQUESTED => 'Requested',\n self::STATUS_GENERATED => 'Generated',\n self::STATUS_SENT => 'Sent',\n self::STATUS_FAILED => 'Failed',\n default => 'Default',\n };\n }\n\n public function getReport(): AutomatedReport\n {\n return $this->getAttribute('report');\n }\n\n public function getFromDate(): ?Carbon\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['from_date'])) {\n return null;\n }\n\n return Carbon::parse($payload['from_date']);\n }\n\n public function getToDate(): ?Carbon\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['to_date'])) {\n return null;\n }\n\n return Carbon::parse($payload['to_date']);\n }\n\n public function getReportType(): ?string\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['report_type'])) {\n return null;\n }\n\n return $payload['report_type'];\n }\n\n public function getGroups(): array\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['group_ids'])) {\n return [];\n }\n\n return $payload['group_ids'];\n }\n\n public function getPdfUrl(): ?string\n {\n $response = $this->getResponse();\n\n return $response['pdf_url'] ?? null;\n }\n\n public function getPodcastAudioUrl(): ?string\n {\n $response = $this->getResponse();\n\n return $response['podcast_audio_url'] ?? null;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Support\\Carbon;\nuse Jiminny\\Traits\\RequiresUUID;\n\n/**\n * Jiminny\\Models\\AutomatedReportResult\n *\n * @property int $id\n * @property string $uuid\n * @property int $report_id\n * @property string|null $name\n * @property int $status\n * @property int $reason\n * @property string $media_type\n * @property int|null $parent_id\n * @property array|null $payload\n * @property array|null $response\n * @property Carbon|null $requested_at\n * @property Carbon|null $generated_at\n * @property Carbon|null $sent_at\n * @property Carbon|null $created_at\n * @property Carbon|null $updated_at\n * @property-read \\Jiminny\\Models\\AutomatedReport $report\n * @property-read AutomatedReportResult|null $parent\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, AutomatedReportResult> $children\n */\nclass AutomatedReportResult extends Model\n{\n use RequiresUUID;\n\n /**\n * Status constants\n */\n public const int STATUS_DEFAULT = 0;\n public const int STATUS_REQUESTED = 1;\n public const int STATUS_GENERATED = 2;\n public const int STATUS_SENT = 3;\n public const int STATUS_FAILED = 4;\n\n /**\n * Reason constants\n */\n public const int REASON_DEFAULT = 0;\n public const int REASON_NOT_ENOUGH_ACTIVITIES = 1;\n public const int REASON_PROPHET_API_ERROR = 2;\n\n protected $table = 'automated_report_results';\n\n /**\n * The attributes that are mass assignable.\n *\n * @var array<int, string>\n */\n protected $fillable = [\n 'report_id',\n 'name',\n 'status',\n 'reason',\n 'media_type',\n 'parent_id',\n 'payload',\n 'response',\n 'requested_at',\n 'generated_at',\n 'sent_at',\n ];\n\n /**\n * Get the attributes that should be cast.\n *\n * @return array<string, string>\n */\n protected function casts(): array\n {\n return [\n 'payload' => 'array',\n 'response' => 'array',\n 'requested_at' => 'datetime',\n 'generated_at' => 'datetime',\n 'sent_at' => 'datetime',\n ];\n }\n\n /**\n * Get the automated report that owns this result.\n *\n * @return BelongsTo\n */\n public function report(): BelongsTo\n {\n return $this->belongsTo(AutomatedReport::class, 'report_id')->withTrashed();\n }\n\n /**\n * Get the parent report result.\n *\n * @return BelongsTo\n */\n public function parent(): BelongsTo\n {\n return $this->belongsTo(self::class, 'parent_id');\n }\n\n /**\n * Get the child report results.\n *\n * @return HasMany\n */\n public function children(): HasMany\n {\n return $this->hasMany(self::class, 'parent_id');\n }\n\n /**\n * Get the ID of the automated report result.\n *\n * @return int\n */\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n /**\n * Get the UUID of the automated report result.\n *\n * @return string\n */\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n /**\n * Get the report ID of the automated report result.\n *\n * @return int\n */\n public function getReportId(): int\n {\n return $this->getAttribute('report_id');\n }\n\n /**\n * Get the name of the automated report result.\n *\n * @return ?string\n */\n public function getName(): ?string\n {\n return $this->getAttribute('name');\n }\n\n /**\n * Get the status of the automated report result.\n *\n * @return int\n */\n public function getStatus(): int\n {\n return $this->getAttribute('status');\n }\n\n /**\n * Get the reason of the automated report result.\n *\n * @return int\n */\n public function getReason(): int\n {\n return $this->getAttribute('reason');\n }\n\n /**\n * Get the media type of the automated report result.\n *\n * @return string\n */\n public function getMediaType(): ?string\n {\n return $this->getAttribute('media_type');\n }\n\n /**\n * Get the parent ID of the automated report result.\n *\n * @return int|null\n */\n public function getParentId(): ?int\n {\n return $this->getAttribute('parent_id');\n }\n\n /**\n * Get the payload of the automated report result.\n *\n * @return array|null\n */\n public function getPayload(): ?array\n {\n return $this->getAttribute('payload');\n }\n\n /**\n * Get the response of the automated report result.\n *\n * @return array|null\n */\n public function getResponse(): ?array\n {\n return $this->getAttribute('response');\n }\n\n /**\n * Get the requested at date of the automated report result.\n *\n * @return Carbon|null\n */\n public function getRequestedAt(): ?Carbon\n {\n return $this->getAttribute('requested_at');\n }\n\n /**\n * Get the generated at date of the automated report result.\n *\n * @return Carbon|null\n */\n public function getGeneratedAt(): ?Carbon\n {\n return $this->getAttribute('generated_at');\n }\n\n /**\n * Get the sent at date of the automated report result.\n *\n * @return Carbon|null\n */\n public function getSentAt(): ?Carbon\n {\n return $this->getAttribute('sent_at');\n }\n\n /**\n * Get the created at date of the automated report result.\n *\n * @return Carbon\n */\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n /**\n * Get the updated at date of the automated report result.\n *\n * @return Carbon\n */\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n /**\n * Check if the report result is in requested status.\n *\n * @return bool\n */\n public function isRequested(): bool\n {\n return $this->getStatus() === self::STATUS_REQUESTED;\n }\n\n /**\n * Check if the report result is in generated status.\n *\n * @return bool\n */\n public function isGenerated(): bool\n {\n return $this->getStatus() === self::STATUS_GENERATED;\n }\n\n /**\n * Check if the report result is in sent status.\n *\n * @return bool\n */\n public function isSent(): bool\n {\n return $this->getStatus() === self::STATUS_SENT;\n }\n\n /**\n * Check if the report result is in failed status.\n *\n * @return bool\n */\n public function isFailed(): bool\n {\n return $this->getStatus() === self::STATUS_FAILED;\n }\n\n public function getStatusLabel(): string\n {\n return match ($this->getStatus()) {\n self::STATUS_REQUESTED => 'Requested',\n self::STATUS_GENERATED => 'Generated',\n self::STATUS_SENT => 'Sent',\n self::STATUS_FAILED => 'Failed',\n default => 'Default',\n };\n }\n\n public function getReport(): AutomatedReport\n {\n return $this->getAttribute('report');\n }\n\n public function getFromDate(): ?Carbon\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['from_date'])) {\n return null;\n }\n\n return Carbon::parse($payload['from_date']);\n }\n\n public function getToDate(): ?Carbon\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['to_date'])) {\n return null;\n }\n\n return Carbon::parse($payload['to_date']);\n }\n\n public function getReportType(): ?string\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['report_type'])) {\n return null;\n }\n\n return $payload['report_type'];\n }\n\n public function getGroups(): array\n {\n $payload = $this->getPayload();\n\n if (empty($payload) || empty($payload['group_ids'])) {\n return [];\n }\n\n return $payload['group_ids'];\n }\n\n public function getPdfUrl(): ?string\n {\n $response = $this->getResponse();\n\n return $response['pdf_url'] ?? null;\n }\n\n public function getPodcastAudioUrl(): ?string\n {\n $response = $this->getResponse();\n\n return $response['podcast_audio_url'] ?? null;\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"bounds":{"left":0.42719415,"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.43583778,"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.44680852,"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.4554521,"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.46409574,"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":"In-Editor Results","depth":4,"bounds":{"left":0.47506648,"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":"Tx: Auto","depth":4,"bounds":{"left":0.48603722,"top":0.09896249,"width":0.024268618,"height":0.01915403},"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,"bounds":{"left":0.51263297,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"bounds":{"left":0.52360374,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7084442,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-8255157670987938192
|
5304222162814503980
|
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
8
1
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Carbon;
use Jiminny\Traits\RequiresUUID;
/**
* Jiminny\Models\AutomatedReportResult
*
* @property int $id
* @property string $uuid
* @property int $report_id
* @property string|null $name
* @property int $status
* @property int $reason
* @property string $media_type
* @property int|null $parent_id
* @property array|null $payload
* @property array|null $response
* @property Carbon|null $requested_at
* @property Carbon|null $generated_at
* @property Carbon|null $sent_at
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
* @property-read \Jiminny\Models\AutomatedReport $report
* @property-read AutomatedReportResult|null $parent
* @property-read \Illuminate\Database\Eloquent\Collection<int, AutomatedReportResult> $children
*/
class AutomatedReportResult extends Model
{
use RequiresUUID;
/**
* Status constants
*/
public const int STATUS_DEFAULT = 0;
public const int STATUS_REQUESTED = 1;
public const int STATUS_GENERATED = 2;
public const int STATUS_SENT = 3;
public const int STATUS_FAILED = 4;
/**
* Reason constants
*/
public const int REASON_DEFAULT = 0;
public const int REASON_NOT_ENOUGH_ACTIVITIES = 1;
public const int REASON_PROPHET_API_ERROR = 2;
protected $table = 'automated_report_results';
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'report_id',
'name',
'status',
'reason',
'media_type',
'parent_id',
'payload',
'response',
'requested_at',
'generated_at',
'sent_at',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'payload' => 'array',
'response' => 'array',
'requested_at' => 'datetime',
'generated_at' => 'datetime',
'sent_at' => 'datetime',
];
}
/**
* Get the automated report that owns this result.
*
* @return BelongsTo
*/
public function report(): BelongsTo
{
return $this->belongsTo(AutomatedReport::class, 'report_id')->withTrashed();
}
/**
* Get the parent report result.
*
* @return BelongsTo
*/
public function parent(): BelongsTo
{
return $this->belongsTo(self::class, 'parent_id');
}
/**
* Get the child report results.
*
* @return HasMany
*/
public function children(): HasMany
{
return $this->hasMany(self::class, 'parent_id');
}
/**
* Get the ID of the automated report result.
*
* @return int
*/
public function getId(): int
{
return $this->getAttribute('id');
}
/**
* Get the UUID of the automated report result.
*
* @return string
*/
public function getUuid(): string
{
return $this->getAttribute('id_string');
}
/**
* Get the report ID of the automated report result.
*
* @return int
*/
public function getReportId(): int
{
return $this->getAttribute('report_id');
}
/**
* Get the name of the automated report result.
*
* @return ?string
*/
public function getName(): ?string
{
return $this->getAttribute('name');
}
/**
* Get the status of the automated report result.
*
* @return int
*/
public function getStatus(): int
{
return $this->getAttribute('status');
}
/**
* Get the reason of the automated report result.
*
* @return int
*/
public function getReason(): int
{
return $this->getAttribute('reason');
}
/**
* Get the media type of the automated report result.
*
* @return string
*/
public function getMediaType(): ?string
{
return $this->getAttribute('media_type');
}
/**
* Get the parent ID of the automated report result.
*
* @return int|null
*/
public function getParentId(): ?int
{
return $this->getAttribute('parent_id');
}
/**
* Get the payload of the automated report result.
*
* @return array|null
*/
public function getPayload(): ?array
{
return $this->getAttribute('payload');
}
/**
* Get the response of the automated report result.
*
* @return array|null
*/
public function getResponse(): ?array
{
return $this->getAttribute('response');
}
/**
* Get the requested at date of the automated report result.
*
* @return Carbon|null
*/
public function getRequestedAt(): ?Carbon
{
return $this->getAttribute('requested_at');
}
/**
* Get the generated at date of the automated report result.
*
* @return Carbon|null
*/
public function getGeneratedAt(): ?Carbon
{
return $this->getAttribute('generated_at');
}
/**
* Get the sent at date of the automated report result.
*
* @return Carbon|null
*/
public function getSentAt(): ?Carbon
{
return $this->getAttribute('sent_at');
}
/**
* Get the created at date of the automated report result.
*
* @return Carbon
*/
public function getCreatedAt(): Carbon
{
return $this->getAttribute('created_at');
}
/**
* Get the updated at date of the automated report result.
*
* @return Carbon
*/
public function getUpdatedAt(): Carbon
{
return $this->getAttribute('updated_at');
}
/**
* Check if the report result is in requested status.
*
* @return bool
*/
public function isRequested(): bool
{
return $this->getStatus() === self::STATUS_REQUESTED;
}
/**
* Check if the report result is in generated status.
*
* @return bool
*/
public function isGenerated(): bool
{
return $this->getStatus() === self::STATUS_GENERATED;
}
/**
* Check if the report result is in sent status.
*
* @return bool
*/
public function isSent(): bool
{
return $this->getStatus() === self::STATUS_SENT;
}
/**
* Check if the report result is in failed status.
*
* @return bool
*/
public function isFailed(): bool
{
return $this->getStatus() === self::STATUS_FAILED;
}
public function getStatusLabel(): string
{
return match ($this->getStatus()) {
self::STATUS_REQUESTED => 'Requested',
self::STATUS_GENERATED => 'Generated',
self::STATUS_SENT => 'Sent',
self::STATUS_FAILED => 'Failed',
default => 'Default',
};
}
public function getReport(): AutomatedReport
{
return $this->getAttribute('report');
}
public function getFromDate(): ?Carbon
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['from_date'])) {
return null;
}
return Carbon::parse($payload['from_date']);
}
public function getToDate(): ?Carbon
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['to_date'])) {
return null;
}
return Carbon::parse($payload['to_date']);
}
public function getReportType(): ?string
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['report_type'])) {
return null;
}
return $payload['report_type'];
}
public function getGroups(): array
{
$payload = $this->getPayload();
if (empty($payload) || empty($payload['group_ids'])) {
return [];
}
return $payload['group_ids'];
}
public function getPdfUrl(): ?string
{
$response = $this->getResponse();
return $response['pdf_url'] ?? null;
}
public function getPodcastAudioUrl(): ?string
{
$response = $this->getResponse();
return $response['podcast_audio_url'] ?? null;
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny...
|
23968
|
NULL
|
NULL
|
NULL
|
|
20974
|
914
|
6
|
2026-05-11T16:48:47.758336+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778518127758_m1.jpg...
|
Firefox
|
JY-20725 add HS rate limit handling on activities JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app — Work...
|
True
|
github.com/jiminny/app/pull/12066
|
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 [URL_WITH_CREDENTIALS]
Show options
LakyLak commented 4 hours ago
LakyLak
LakyLak
commented
4 hours ago
4 hours ago
JIRA: JY-20725
JIRA:
JY-20725
JY-20725
Changes:
Changes:
Adds
HandleHubspotRateLimit
middleware (release jobs with delay)
Adds
executeRequest
wrapper in Hubspot Client. It handles 429 errors and throws
RateLimitException
Add or remove reactions
LakyLak
LakyLak
added
2
commits
4 hours ago
4 hours ago
@LakyLak
JY-20725
JY-20725
add HS rate limit handling on activities rematching
add HS rate limit handling on activities rematching
8 / 10 checks OK
44d5678
44d5678
@LakyLak
JY-20725
JY-20725
add tests
add tests
11 / 12 checks OK
cbed2c9
cbed2c9
@sonarqubecloud
Show options
sonarqubecloud Bot commented 3 hours ago
sonarqubecloud
sonarqubecloud
Bot
commented
3 hours ago
3 hours ago
Quality Gate Failed Quality Gate failed
Quality Gate Failed
Quality Gate failed
Failed conditions
34.4% Coverage on New Code
34.4% Coverage on New Code
(required ≥ 70%)
See analysis details on SonarQube Cloud
See analysis details on SonarQube Cloud
Add or remove reactions
@LakyLak
Show options
Author
LakyLak commented 3 hours ago
LakyLak
LakyLak
commented
3 hours ago
3 hours ago
@claude
@claude
Add or remove reactions
react with eyes
👀
1
@claude
Show options
claude Bot commented 3 hours ago •
claude
claude
Bot
commented
3 hours ago...
|
[{"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":true},{"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":"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":"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":"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":false,"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":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"on_screen":false,"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":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"on_screen":false,"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":false,"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":false,"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":false,"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":false,"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":false,"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":false,"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":false,"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":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (34)","depth":12,"on_screen":false,"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":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"34","depth":14,"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":"AXLink","text":"Agents","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality (4)","depth":12,"on_screen":false,"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":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4","depth":14,"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":"AXLink","text":"Insights","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"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":"AXHeading","text":"Important update","depth":10,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"on_screen":false,"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":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"on_screen":false,"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":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"on_screen":false,"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":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"JY-20725 add HS rate limit handling on activities rematching #12066 Edit title","depth":13,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"#","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12066","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Edit title","depth":14,"on_screen":false,"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":false,"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":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Code","depth":13,"on_screen":false,"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":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":15,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"wants to merge 4 commits into","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"master","depth":15,"on_screen":false,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"master","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"from","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20725-handle-HS-search-rate-limit","depth":16,"on_screen":false,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725-handle-HS-search-rate-limit","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy head branch name to clipboard","depth":16,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lines changed: 757 additions & 249 deletions","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Conversation (3)","depth":16,"on_screen":false,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Conversation","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Commits (4)","depth":16,"on_screen":false,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Commits","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Checks (2)","depth":16,"on_screen":false,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Checks","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Files changed (12)","depth":16,"on_screen":false,"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":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"JY-20725 add HS rate limit handling on activities rematching #12066 LakyLak wants to merge 4 commits into master from JY-20725-handle-HS-search-rate-limit Copy head branch name to clipboard","depth":14,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20725 add HS rate limit handling on activities rematching","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"#","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12066","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":18,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":19,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"wants to merge 4 commits into","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"master","depth":18,"on_screen":true,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"master","depth":19,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"from","depth":19,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20725-handle-HS-search-rate-limit","depth":19,"on_screen":true,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725-handle-HS-search-rate-limit","depth":20,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy head branch name to clipboard","depth":19,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Conversation","depth":12,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show options","depth":15,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"LakyLak commented 4 hours ago","depth":14,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":16,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commented","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"4 hours ago","depth":15,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"4 hours ago","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"JIRA: JY-20725","depth":16,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JIRA:","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20725","depth":17,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Changes:","depth":16,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Changes:","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Adds","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"HandleHubspotRateLimit","depth":19,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"middleware (release jobs with delay)","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Adds","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"executeRequest","depth":19,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"wrapper in Hubspot Client. It handles 429 errors and throws","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"RateLimitException","depth":19,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add or remove reactions","depth":16,"on_screen":false,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"LakyLak","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"added","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commits","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"4 hours ago","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"4 hours ago","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20725","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"add HS rate limit handling on activities rematching","depth":14,"on_screen":false,"help_text":"JY-20725 add HS rate limit handling on activities rematching","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"add HS rate limit handling on activities rematching","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":14,"on_screen":false,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"44d5678","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"44d5678","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20725","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"add tests","depth":14,"on_screen":false,"help_text":"JY-20725 add tests","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"add tests","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":14,"on_screen":false,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"cbed2c9","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"cbed2c9","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@sonarqubecloud","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show options","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"sonarqubecloud Bot commented 3 hours ago","depth":13,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"sonarqubecloud","depth":15,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"sonarqubecloud","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Bot","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commented","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 hours ago","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3 hours ago","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Quality Gate Failed Quality Gate failed","depth":16,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"Quality Gate Failed","depth":17,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Quality Gate failed","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Failed conditions","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"34.4% Coverage on New Code","depth":17,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"34.4% Coverage on New Code","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(required ≥ 70%)","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See analysis details on SonarQube Cloud","depth":17,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See analysis details on SonarQube Cloud","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add or remove reactions","depth":15,"on_screen":false,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"@LakyLak","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show options","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Author","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"LakyLak commented 3 hours ago","depth":13,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":15,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commented","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 hours ago","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3 hours ago","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@claude","depth":17,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"@claude","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add or remove reactions","depth":15,"on_screen":false,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"react with eyes","depth":14,"on_screen":false,"role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"👀","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@claude","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show options","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"claude Bot commented 3 hours ago •","depth":13,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"claude","depth":15,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"claude","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Bot","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commented","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 hours ago","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-8254266499044747583
|
6919647721955045504
|
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 [URL_WITH_CREDENTIALS]
Show options
LakyLak commented 4 hours ago
LakyLak
LakyLak
commented
4 hours ago
4 hours ago
JIRA: JY-20725
JIRA:
JY-20725
JY-20725
Changes:
Changes:
Adds
HandleHubspotRateLimit
middleware (release jobs with delay)
Adds
executeRequest
wrapper in Hubspot Client. It handles 429 errors and throws
RateLimitException
Add or remove reactions
LakyLak
LakyLak
added
2
commits
4 hours ago
4 hours ago
@LakyLak
JY-20725
JY-20725
add HS rate limit handling on activities rematching
add HS rate limit handling on activities rematching
8 / 10 checks OK
44d5678
44d5678
@LakyLak
JY-20725
JY-20725
add tests
add tests
11 / 12 checks OK
cbed2c9
cbed2c9
@sonarqubecloud
Show options
sonarqubecloud Bot commented 3 hours ago
sonarqubecloud
sonarqubecloud
Bot
commented
3 hours ago
3 hours ago
Quality Gate Failed Quality Gate failed
Quality Gate Failed
Quality Gate failed
Failed conditions
34.4% Coverage on New Code
34.4% Coverage on New Code
(required ≥ 70%)
See analysis details on SonarQube Cloud
See analysis details on SonarQube Cloud
Add or remove reactions
@LakyLak
Show options
Author
LakyLak commented 3 hours ago
LakyLak
LakyLak
commented
3 hours ago
3 hours ago
@claude
@claude
Add or remove reactions
react with eyes
👀
1
@claude
Show options
claude Bot commented 3 hours ago •
claude
claude
Bot
commented
3 hours ago...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
24510
|
1023
|
28
|
2026-05-12T09:19:14.473086+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778577554473_m2.jpg...
|
Firefox
|
(172) World War II Every Day with Army Sizes - You (172) World War II Every Day with Army Sizes - YouTube — Personal...
|
True
|
www.youtube.com/watch?v=1CqGeAmVu1I
|
monitor_2
|
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
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
New Tab
New Tab
Screenpipe — Archive
Screenpipe — Archive
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
(172) World War II Every Day with Army Sizes - YouTube
Mute tab
(172) World War II Every Day with Army Sizes - YouTube
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Sprievodca
Domovská stránka YouTube
BG
Preskočiť navigáciu
Preskočiť navigáciu
Karol Wojtyla speaking langauges
Karol Wojtyla speaking langauges
Vymazať vyhľadávací dopyt
Search
Vyhľadávať hlasom
Vytvoriť
Vytvoriť
Upozornenia
9+
Ponuka účtu
Klávesová skratka pre akciu Pozastaviť: k
Stlmiť (m)
0 min 2 s z 13 min 14 s
0:02
/
13:14
Automatické prehrávanie je zapnuté
Titulky alebo skryté titulky sú nedostupné
Nastavenia
Režim kina (t)
Celá obrazovka (f)
World War II Every Day with Army Sizes
World War II Every Day with Army Sizes
Christopher
Christopher
118 tis. odberateľov
Prihlásiť sa na odber kanála Christopher.
Odoberať
Označiť, že sa mi toto video páči, tak ako 415 684 ďalším osobám
415 tis.
Toto video sa mi nepáči
Zdieľať
Zdieľať
Uložiť do zoznamu
Uložiť
Vďaka
Vďaka
Ďalšie akcie
45 mil. zhliadnutí
pred 4 rokmi
Hi everyone, I'm sorry for the very long wait in uploads, however, hopefully you will understand why, as it has taken me almost a year to research and produce this video.
…
...viac
...viac
54 130 komentárov
54 130
komentárov
Zoradiť komentáre
Zoradiť podľa
Pridajte komentár…
@Woodscraps-lr5vz
@Woodscraps-lr5vz
@Woodscraps-lr5vz
@Woodscraps-lr5vz
pred 4 rokmi
pred 4 rokmi
Definitely shows how WWII was much much more of a Soviet-German thing in Europe than it really was an American thing.
Označiť, že sa vám tento komentár páči, tak ako 38 tis. ďalším ľuďom
38 tis.
Tento komentár sa mi nepáči
Ponuka akcií
829 odpovedí
829 odpovedí
@kingbread5808
@kingbread5808
@kingbread5808
@kingbread5808
pred 4 rokmi
pred 4 rokmi
I’ve never realised how terrifyingly close the Germans were to Moscow.
Označiť, že sa vám tento komentár páči, tak ako 8,3 tis. ďalším ľuďom
8,3 tis.
Tento komentár sa mi nepáči
Odpovedať
Odpovedať
Ponuka akcií
538 odpovedí
538 odpovedí
@Zeitgeist-ip1eu
@Zeitgeist-ip1eu
@Zeitgeist-ip1eu
@Zeitgeist-ip1eu
pred 3 rokmi
pred 3 rokmi
Fun fact: a tractor factory in Stalingrad kept defending itself as long as whole France did
Označiť, že sa vám tento komentár páči, tak ako 12 tis. ďalším ľuďom
12 tis.
Tento komentár sa mi nepáči
Odpovedať
Odpovedať
Ponuka akcií
245 odpovedí
245 odpovedí
@stoney88mm
@stoney88mm
@stoney88mm
@stoney88mm
pred 1 mesiacom
pred 1 mesiacom
Crazy to think that the Soviets stood strong even with 27M casualties, wow.
Označiť, že sa vám tento komentár páči, tak ako 8 ďalším ľuďom
8
Tento komentár sa mi nepáči
Odpovedať
Odpovedať
Ponuka akcií
@mikeshinoda703
@mikeshinoda703
@mikeshinoda703
@mikeshinoda703
pred 3 rokmi
pred 3 rokmi
Hollywood always portrays WW2 from such a USA-centric perspective, but the sheer volume of conflict that commenced on the eastern front is crazy. Apparently 80% of the axis army was there.
Označiť, že sa vám tento komentár páči, tak ako 19 tis. ďalším ľuďom
19 tis.
Tento komentár sa mi nepáči
Odpovedať
Odpovedať
Ponuka akcií
758 odpovedí
758 odpovedí
@ande991
@ande991
@ande991
@ande991
pred 3 rokmi
pred 3 rokmi
Soviets: ”we have 4 million soldiers”
Germany:
encircles 500k men...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.5,"top":0.0518755,"width":0.06881649,"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.51329786,"top":0.06304868,"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.5,"top":0.08459697,"width":0.06881649,"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.51329786,"top":0.09577015,"width":0.037898935,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"All docs · AFFiNE","depth":4,"bounds":{"left":0.5,"top":0.11731844,"width":0.06881649,"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.51329786,"top":0.12849163,"width":0.029587766,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"bounds":{"left":0.5,"top":0.15003991,"width":0.06881649,"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.51329786,"top":0.16121309,"width":0.036901597,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.5,"top":0.18276137,"width":0.06881649,"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.51329786,"top":0.19393456,"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.5,"top":0.21548285,"width":0.06881649,"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.51329786,"top":0.22665602,"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.5,"top":0.2482043,"width":0.06881649,"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.51329786,"top":0.25937748,"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.5,"top":0.28092578,"width":0.06881649,"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.51329786,"top":0.29209897,"width":0.03756649,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"(172) World War II Every Day with Army Sizes - YouTube","depth":4,"bounds":{"left":0.5,"top":0.31364724,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Mute tab","depth":5,"bounds":{"left":0.5114694,"top":0.32083002,"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":"(172) World War II Every Day with Army Sizes - YouTube","depth":5,"bounds":{"left":0.52011305,"top":0.32482043,"width":0.0965758,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.55651593,"top":0.32083002,"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.5028258,"top":0.34796488,"width":0.06333112,"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.5028258,"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.51379657,"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.5249335,"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.53607047,"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.5472075,"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":"Sprievodca","depth":13,"bounds":{"left":0.5767952,"top":0.06464485,"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":"AXLink","text":"Domovská stránka YouTube","depth":12,"bounds":{"left":0.5874335,"top":0.0518755,"width":0.04089096,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"BG","depth":13,"bounds":{"left":0.625,"top":0.061452515,"width":0.0043218085,"height":0.009577015},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Preskočiť navigáciu","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Preskočiť navigáciu","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Karol Wojtyla speaking langauges","depth":15,"bounds":{"left":0.6843417,"top":0.06464485,"width":0.15292554,"height":0.01915403},"on_screen":true,"value":"Karol Wojtyla speaking langauges","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Karol Wojtyla speaking langauges","depth":16,"bounds":{"left":0.6843417,"top":0.066640064,"width":0.07945479,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Vymazať vyhľadávací dopyt","depth":14,"bounds":{"left":0.84491354,"top":0.058260176,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search","depth":13,"bounds":{"left":0.8568817,"top":0.058260176,"width":0.021276595,"height":0.031923383},"on_screen":true,"help_text":"Hľadať","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Vyhľadávať hlasom","depth":14,"bounds":{"left":0.8834774,"top":0.058260176,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Vytvoriť","depth":14,"bounds":{"left":0.923371,"top":0.059856344,"width":0.03474069,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Vytvoriť","depth":17,"bounds":{"left":0.9366689,"top":0.06783719,"width":0.016123671,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Upozornenia","depth":15,"bounds":{"left":0.96077126,"top":0.058260176,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"9+","depth":17,"bounds":{"left":0.9694149,"top":0.06384677,"width":0.004488032,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Ponuka účtu","depth":14,"bounds":{"left":0.97672874,"top":0.060654428,"width":0.017952127,"height":0.027134877},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Klávesová skratka pre akciu Pozastaviť: k","depth":20,"bounds":{"left":0.578125,"top":0.44333598,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Stlmiť (m)","depth":21,"bounds":{"left":0.59541225,"top":0.44333598,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"0 min 2 s z 13 min 14 s","depth":22,"bounds":{"left":0.61668885,"top":0.44333598,"width":0.024933511,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0:02","depth":23,"bounds":{"left":0.61668885,"top":0.45291302,"width":0.009142287,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":23,"bounds":{"left":0.6258311,"top":0.45291302,"width":0.0043218085,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13:14","depth":23,"bounds":{"left":0.63015294,"top":0.45291302,"width":0.011469414,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Automatické prehrávanie je zapnuté","depth":19,"bounds":{"left":0.7706117,"top":0.44333598,"width":0.015957447,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Titulky alebo skryté titulky sú nedostupné","depth":19,"bounds":{"left":0.7865692,"top":0.44333598,"width":0.015957447,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Nastavenia","depth":19,"bounds":{"left":0.8025266,"top":0.44333598,"width":0.015957447,"height":0.031923383},"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":"Režim kina (t)","depth":19,"bounds":{"left":0.81848407,"top":0.44333598,"width":0.015957447,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Celá obrazovka (f)","depth":19,"bounds":{"left":0.8344415,"top":0.44333598,"width":0.015957447,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"World War II Every Day with Army Sizes","depth":16,"bounds":{"left":0.57413566,"top":0.49122107,"width":0.28158244,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"World War II Every Day with Army Sizes","depth":18,"bounds":{"left":0.57413566,"top":0.49281725,"width":0.11702128,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Christopher","depth":22,"bounds":{"left":0.59142286,"top":0.5211492,"width":0.02825798,"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":"Christopher","depth":23,"bounds":{"left":0.59142286,"top":0.5223464,"width":0.027759308,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"118 tis. odberateľov","depth":20,"bounds":{"left":0.59142286,"top":0.53990424,"width":0.03523936,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Prihlásiť sa na odber kanála Christopher.","depth":20,"bounds":{"left":0.6359708,"top":0.52274543,"width":0.029920213,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Odoberať","depth":23,"bounds":{"left":0.6412899,"top":0.5303272,"width":0.019281914,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Označiť, že sa mi toto video páči, tak ako 415 684 ďalším osobám","depth":24,"bounds":{"left":0.68567157,"top":0.52274543,"width":0.034075797,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"415 tis.","depth":26,"bounds":{"left":0.6989694,"top":0.5303272,"width":0.015458777,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Toto video sa mi nepáči","depth":24,"bounds":{"left":0.71974736,"top":0.52274543,"width":0.017287234,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Zdieľať","depth":22,"bounds":{"left":0.7396942,"top":0.52274543,"width":0.033410903,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Zdieľať","depth":24,"bounds":{"left":0.75299203,"top":0.5303272,"width":0.014793883,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Uložiť do zoznamu","depth":22,"bounds":{"left":0.77576464,"top":0.52274543,"width":0.030585106,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Uložiť","depth":24,"bounds":{"left":0.7890625,"top":0.5303272,"width":0.011968086,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Vďaka","depth":22,"bounds":{"left":0.8090093,"top":0.52274543,"width":0.032081116,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Vďaka","depth":24,"bounds":{"left":0.82230717,"top":0.5303272,"width":0.013464096,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Ďalšie akcie","depth":20,"bounds":{"left":0.84375,"top":0.52274543,"width":0.011968086,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"45 mil. zhliadnutí","depth":21,"bounds":{"left":0.578125,"top":0.5746209,"width":0.035738032,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"pred 4 rokmi","depth":21,"bounds":{"left":0.61619014,"top":0.5746209,"width":0.026097074,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hi everyone, I'm sorry for the very long wait in uploads, however, hopefully you will understand why, as it has taken me almost a year to research and produce this video.","depth":21,"bounds":{"left":0.578125,"top":0.5905826,"width":0.27144283,"height":0.029130088},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"…","depth":21,"bounds":{"left":0.57928854,"top":0.62250596,"width":0.0031582448,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"...viac","depth":19,"bounds":{"left":0.57912236,"top":0.6209098,"width":0.013297873,"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":"...viac","depth":20,"bounds":{"left":0.579621,"top":0.62250596,"width":0.012300532,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"54 130 komentárov","depth":19,"bounds":{"left":0.57413566,"top":0.66560256,"width":0.058011968,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"54 130","depth":21,"bounds":{"left":0.57413566,"top":0.6671987,"width":0.020777926,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"komentárov","depth":21,"bounds":{"left":0.59491354,"top":0.6671987,"width":0.03723404,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Zoradiť komentáre","depth":24,"bounds":{"left":0.6427859,"top":0.6652035,"width":0.040724736,"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":"AXStaticText","text":"Zoradiť podľa","depth":26,"bounds":{"left":0.6534242,"top":0.6679968,"width":0.030086435,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Pridajte komentár…","depth":19,"bounds":{"left":0.58610374,"top":0.7086991,"width":0.039727394,"height":0.0131683955},"on_screen":true,"value":"Pridajte komentár…","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"@Woodscraps-lr5vz","depth":21,"bounds":{"left":0.57413566,"top":0.75259376,"width":0.011968086,"height":0.0311253},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"@Woodscraps-lr5vz","depth":23,"bounds":{"left":0.59142286,"top":0.75259376,"width":0.040059842,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"@Woodscraps-lr5vz","depth":24,"bounds":{"left":0.59142286,"top":0.75259376,"width":0.03873005,"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":"@Woodscraps-lr5vz","depth":25,"bounds":{"left":0.59142286,"top":0.75339186,"width":0.03873005,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"pred 4 rokmi","depth":24,"bounds":{"left":0.6314827,"top":0.7529928,"width":0.022273935,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pred 4 rokmi","depth":25,"bounds":{"left":0.6314827,"top":0.75418997,"width":0.022273935,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Definitely shows how WWII was much much more of a Soviet-German thing in Europe than it really was an American thing.","depth":24,"bounds":{"left":0.59142286,"top":0.7717478,"width":0.25132978,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Označiť, že sa vám tento komentár páči, tak ako 38 tis. ďalším ľuďom","depth":24,"bounds":{"left":0.5887633,"top":0.7893057,"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":"38 tis.","depth":24,"bounds":{"left":0.5994016,"top":0.7964884,"width":0.010804521,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Tento komentár sa mi nepáči","depth":24,"bounds":{"left":0.6128657,"top":0.7893057,"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":"Ponuka akcií","depth":22,"bounds":{"left":0.8424202,"top":0.7430168,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"829 odpovedí","depth":22,"bounds":{"left":0.58610374,"top":0.8244214,"width":0.046875,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"829 odpovedí","depth":25,"bounds":{"left":0.59142286,"top":0.8324022,"width":0.02825798,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"@kingbread5808","depth":21,"bounds":{"left":0.57413566,"top":0.8659218,"width":0.011968086,"height":0.0311253},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"@kingbread5808","depth":23,"bounds":{"left":0.59142286,"top":0.8659218,"width":0.034242023,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"@kingbread5808","depth":24,"bounds":{"left":0.59142286,"top":0.8659218,"width":0.032912236,"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":"@kingbread5808","depth":25,"bounds":{"left":0.59142286,"top":0.8667199,"width":0.032912236,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"pred 4 rokmi","depth":24,"bounds":{"left":0.6256649,"top":0.86632085,"width":0.022273935,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pred 4 rokmi","depth":25,"bounds":{"left":0.6256649,"top":0.86751795,"width":0.022273935,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"I’ve never realised how terrifyingly close the Germans were to Moscow.","depth":24,"bounds":{"left":0.59142286,"top":0.8850758,"width":0.1456117,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Označiť, že sa vám tento komentár páči, tak ako 8,3 tis. ďalším ľuďom","depth":24,"bounds":{"left":0.5887633,"top":0.90263367,"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":"8,3 tis.","depth":24,"bounds":{"left":0.5994016,"top":0.90981644,"width":0.011635638,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Tento komentár sa mi nepáči","depth":24,"bounds":{"left":0.6136968,"top":0.90263367,"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":"Odpovedať","depth":24,"bounds":{"left":0.62699467,"top":0.90263367,"width":0.027426861,"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":"Odpovedať","depth":27,"bounds":{"left":0.63098407,"top":0.90981644,"width":0.019448139,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Ponuka akcií","depth":22,"bounds":{"left":0.8424202,"top":0.85634476,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"538 odpovedí","depth":22,"bounds":{"left":0.58610374,"top":0.9377494,"width":0.046875,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"538 odpovedí","depth":25,"bounds":{"left":0.59142286,"top":0.94573027,"width":0.02825798,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"@Zeitgeist-ip1eu","depth":21,"bounds":{"left":0.57413566,"top":0.9792498,"width":0.011968086,"height":0.020750225},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"@Zeitgeist-ip1eu","depth":23,"bounds":{"left":0.59142286,"top":0.9792498,"width":0.034408245,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"@Zeitgeist-ip1eu","depth":24,"bounds":{"left":0.59142286,"top":0.9792498,"width":0.03307846,"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":"@Zeitgeist-ip1eu","depth":25,"bounds":{"left":0.59142286,"top":0.9800479,"width":0.03307846,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"pred 3 rokmi","depth":24,"bounds":{"left":0.6258311,"top":0.9796488,"width":0.022107713,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pred 3 rokmi","depth":25,"bounds":{"left":0.6258311,"top":0.980846,"width":0.022107713,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fun fact: a tractor factory in Stalingrad kept defending itself as long as whole France did","depth":24,"bounds":{"left":0.59142286,"top":0.99840385,"width":0.18085106,"height":0.0015961528},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Označiť, že sa vám tento komentár páči, tak ako 12 tis. ďalším ľuďom","depth":24,"bounds":{"left":0.5887633,"top":1.0,"width":0.010638298,"height":-0.015961647},"on_screen":false,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"12 tis.","depth":24,"bounds":{"left":0.5994016,"top":1.0,"width":0.010804521,"height":-0.023144484},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Tento komentár sa mi nepáči","depth":24,"bounds":{"left":0.6128657,"top":1.0,"width":0.010638298,"height":-0.015961647},"on_screen":false,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Odpovedať","depth":24,"bounds":{"left":0.62616354,"top":1.0,"width":0.027426861,"height":-0.015961647},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Odpovedať","depth":27,"bounds":{"left":0.63015294,"top":1.0,"width":0.019448139,"height":-0.023144484},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Ponuka akcií","depth":22,"bounds":{"left":0.8424202,"top":0.9696728,"width":0.013297873,"height":0.0303272},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"245 odpovedí","depth":22,"bounds":{"left":0.58610374,"top":1.0,"width":0.046875,"height":-0.051077366},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"245 odpovedí","depth":25,"bounds":{"left":0.59142286,"top":1.0,"width":0.02825798,"height":-0.05905831},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"@stoney88mm","depth":21,"bounds":{"left":0.57413566,"top":1.0,"width":0.011968086,"height":-0.092577815},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"@stoney88mm","depth":23,"bounds":{"left":0.59142286,"top":1.0,"width":0.030585106,"height":-0.092577815},"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"@stoney88mm","depth":24,"bounds":{"left":0.59142286,"top":1.0,"width":0.02925532,"height":-0.092577815},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"@stoney88mm","depth":25,"bounds":{"left":0.59142286,"top":1.0,"width":0.02925532,"height":-0.09337592},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"pred 1 mesiacom","depth":24,"bounds":{"left":0.62200797,"top":1.0,"width":0.030751329,"height":-0.09297681},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pred 1 mesiacom","depth":25,"bounds":{"left":0.62200797,"top":1.0,"width":0.030751329,"height":-0.09417403},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Crazy to think that the Soviets stood strong even with 27M casualties, wow.","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Označiť, že sa vám tento komentár páči, tak ako 8 ďalším ľuďom","depth":24,"on_screen":false,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"8","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Tento komentár sa mi nepáči","depth":24,"on_screen":false,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Odpovedať","depth":24,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Odpovedať","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Ponuka akcií","depth":22,"bounds":{"left":0.8424202,"top":1.0,"width":0.013297873,"height":-0.08300078},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"@mikeshinoda703","depth":21,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"@mikeshinoda703","depth":23,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"@mikeshinoda703","depth":24,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"@mikeshinoda703","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"pred 3 rokmi","depth":24,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pred 3 rokmi","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hollywood always portrays WW2 from such a USA-centric perspective, but the sheer volume of conflict that commenced on the eastern front is crazy. Apparently 80% of the axis army was there.","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Označiť, že sa vám tento komentár páči, tak ako 19 tis. ďalším ľuďom","depth":24,"on_screen":false,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"19 tis.","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Tento komentár sa mi nepáči","depth":24,"on_screen":false,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Odpovedať","depth":24,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Odpovedať","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Ponuka akcií","depth":22,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"758 odpovedí","depth":22,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"758 odpovedí","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"@ande991","depth":21,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"@ande991","depth":23,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"@ande991","depth":24,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"@ande991","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"pred 3 rokmi","depth":24,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pred 3 rokmi","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Soviets: ”we have 4 million soldiers”\nGermany:","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"encircles 500k men","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8253350582437520057
|
2064922992814446222
|
visual_change
|
accessibility
|
NULL
|
New Tab
New Tab
Screenpipe — Archive
Screenpipe — New Tab
New Tab
Screenpipe — Archive
Screenpipe — Archive
All docs · AFFiNE
All docs · AFFiNE
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
New Tab
New Tab
Screenpipe — Archive
Screenpipe — Archive
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
(172) World War II Every Day with Army Sizes - YouTube
Mute tab
(172) World War II Every Day with Army Sizes - YouTube
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Sprievodca
Domovská stránka YouTube
BG
Preskočiť navigáciu
Preskočiť navigáciu
Karol Wojtyla speaking langauges
Karol Wojtyla speaking langauges
Vymazať vyhľadávací dopyt
Search
Vyhľadávať hlasom
Vytvoriť
Vytvoriť
Upozornenia
9+
Ponuka účtu
Klávesová skratka pre akciu Pozastaviť: k
Stlmiť (m)
0 min 2 s z 13 min 14 s
0:02
/
13:14
Automatické prehrávanie je zapnuté
Titulky alebo skryté titulky sú nedostupné
Nastavenia
Režim kina (t)
Celá obrazovka (f)
World War II Every Day with Army Sizes
World War II Every Day with Army Sizes
Christopher
Christopher
118 tis. odberateľov
Prihlásiť sa na odber kanála Christopher.
Odoberať
Označiť, že sa mi toto video páči, tak ako 415 684 ďalším osobám
415 tis.
Toto video sa mi nepáči
Zdieľať
Zdieľať
Uložiť do zoznamu
Uložiť
Vďaka
Vďaka
Ďalšie akcie
45 mil. zhliadnutí
pred 4 rokmi
Hi everyone, I'm sorry for the very long wait in uploads, however, hopefully you will understand why, as it has taken me almost a year to research and produce this video.
…
...viac
...viac
54 130 komentárov
54 130
komentárov
Zoradiť komentáre
Zoradiť podľa
Pridajte komentár…
@Woodscraps-lr5vz
@Woodscraps-lr5vz
@Woodscraps-lr5vz
@Woodscraps-lr5vz
pred 4 rokmi
pred 4 rokmi
Definitely shows how WWII was much much more of a Soviet-German thing in Europe than it really was an American thing.
Označiť, že sa vám tento komentár páči, tak ako 38 tis. ďalším ľuďom
38 tis.
Tento komentár sa mi nepáči
Ponuka akcií
829 odpovedí
829 odpovedí
@kingbread5808
@kingbread5808
@kingbread5808
@kingbread5808
pred 4 rokmi
pred 4 rokmi
I’ve never realised how terrifyingly close the Germans were to Moscow.
Označiť, že sa vám tento komentár páči, tak ako 8,3 tis. ďalším ľuďom
8,3 tis.
Tento komentár sa mi nepáči
Odpovedať
Odpovedať
Ponuka akcií
538 odpovedí
538 odpovedí
@Zeitgeist-ip1eu
@Zeitgeist-ip1eu
@Zeitgeist-ip1eu
@Zeitgeist-ip1eu
pred 3 rokmi
pred 3 rokmi
Fun fact: a tractor factory in Stalingrad kept defending itself as long as whole France did
Označiť, že sa vám tento komentár páči, tak ako 12 tis. ďalším ľuďom
12 tis.
Tento komentár sa mi nepáči
Odpovedať
Odpovedať
Ponuka akcií
245 odpovedí
245 odpovedí
@stoney88mm
@stoney88mm
@stoney88mm
@stoney88mm
pred 1 mesiacom
pred 1 mesiacom
Crazy to think that the Soviets stood strong even with 27M casualties, wow.
Označiť, že sa vám tento komentár páči, tak ako 8 ďalším ľuďom
8
Tento komentár sa mi nepáči
Odpovedať
Odpovedať
Ponuka akcií
@mikeshinoda703
@mikeshinoda703
@mikeshinoda703
@mikeshinoda703
pred 3 rokmi
pred 3 rokmi
Hollywood always portrays WW2 from such a USA-centric perspective, but the sheer volume of conflict that commenced on the eastern front is crazy. Apparently 80% of the axis army was there.
Označiť, že sa vám tento komentár páči, tak ako 19 tis. ďalším ľuďom
19 tis.
Tento komentár sa mi nepáči
Odpovedať
Odpovedať
Ponuka akcií
758 odpovedí
758 odpovedí
@ande991
@ande991
@ande991
@ande991
pred 3 rokmi
pred 3 rokmi
Soviets: ”we have 4 million soldiers”
Germany:
encircles 500k men...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
11914
|
531
|
9
|
2026-05-09T08:09:12.676719+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778314152676_m1.jpg...
|
Firefox
|
Електронно банкиране ДСК Директ от Банка ДСК — Per Електронно банкиране ДСК Директ от Банка ДСК — Personal...
|
True
|
www.dskdirect.bg/page/default.aspx?user_id=1130906 www.dskdirect.bg/page/default.aspx?user_id=11309067&session_id=51faf0494b7e11f19be7005056b08056ImAgaqvVfd74VO0qZJ2DAOK-Ch6nf7D-q9D0X%2fT5Sa6XCG%2ff8wKZN-T5Tsjny7uz28IzZWLAWXb66J-J4wZTLw%3d%3dU&xml_id=/bg-BG/01Individuals/02Accounts/07Excerpts/&SelectedAccountID=26574472...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
report(2).csv
Completed — 2.6 KB
Show in Finder
re report(2).csv
Completed — 2.6 KB
Show in Finder
report(1).csv
Completed — 1.4 KB
Show in Finder
Show all downloads
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
Оптичен интернет за дома - EON телевизия | Vivacom | 5G
Оптичен интернет за дома - EON телевизия | Vivacom | 5G
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - [EMAIL] - Gmail
[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - [EMAIL] - Gmail
New Tab
New Tab
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Select: payments - db - Adminer
Select: payments - db - Adminer
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
LUKAS KOVALIK
1 Входяща поща
1
Входяща поща
Обратна връзка
Обратна връзка
English
English
Изход
Изход
СРЕДСТВА
СРЕДСТВА
КРЕДИТИ
КРЕДИТИ
КАРТИ
КАРТИ
БИТОВИ СМЕТКИ
БИТОВИ СМЕТКИ
ПРЕВОДИ
ПРЕВОДИ
СПЕСТЯВАНЕ
СПЕСТЯВАНЕ
ФОНДОВЕ
ФОНДОВЕ
ЗАЯВКИ
ЗАЯВКИ
ИЗВЕСТИЯ
ИЗВЕСТИЯ
СМАРТ ПРИЛОЖЕНИЯ
СМАРТ ПРИЛОЖЕНИЯ
НАСТРОЙКИ
НАСТРОЙКИ
С какво разполагам
С какво разполагам
Извлечения PDF
Извлечения PDF
Извлечения за период / месец
Извлечения за период / месец
Движения по сметки
Движения по сметки
Справка за IBAN
Справка за IBAN
Движения
Движения
Управление на бърз достъп до менюта.
Банков клиент
Сметка
Движения
Основание
Отсрещна страна - име
Отсрещна страна - сметка
Последните
Последните
10
За период от
За период от
09.05.2026
до
09.05.2026
Днес
Днес
От началото на месеца
От началото на месеца
От началото на годината
От началото на годината
Сума от
до
Експорт към файл
Покажи
Покажи
: No sort applied, sorting is disabled
Дата: No sort applied, activate to apply an ascending sort
▲
ДАТА
▼
Основание: No sort applied, activate to apply an ascending sort
▲
ОСНОВАНИЕ
▼
Наредител/Получател: No sort applied, activate to apply an ascending sort
▲
НАРЕДИТЕЛ/ПОЛУЧАТЕЛ
▼
Номер сметка на наредителя / получателя: No sort applied, activate to apply an ascending sort
▲
НОМЕР СМЕТКА НА НАРЕДИТЕЛЯ / ПОЛУЧАТЕЛЯ
▼
Дебит: No sort applied, activate to apply an ascending sort
▲
ДЕБИТ
▼
Кредит: No sort applied, activate to apply an ascending sort
▲
КРЕДИТ
▼
04.05.2026
04.05.2026 ПРОФЕСИОНАЛЕН ДОМОУАБ.N. 14044121 НАШИЯТ ВХОД ООД
КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ
[IBAN]
17.93
04.05.2026
04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
[IBAN]
8.44
04.05.2026
04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
[IBAN]
47.63
04.05.2026
04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
[IBAN]
0.09
04.05.2026
04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
[IBAN]
29.54
04.05.2026
04.05.2026 ПРИРОДЕН ГАЗ АБ.N. 1000083763 OVERGAS
ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА
[IBAN]
14.27
04.05.2026
ДАНИЕЛ КОВАЛИК МАЙ
ЧЦДГ МИЛА
[IBAN]
460.00
30.04.2026
ТАКСА ПАКЕТНО ОБСЛУЖВАНЕ
[CREDIT_CARD]
10.22
30.04.2026
ЗАПЛАТА ЗА МЕСЕЦ 04.2026 OPNAT 0
ВЕДА ПЕЙРОЛ ООД
[IBAN]
4 325.26
22.04.2026
ЗАХРАНВАНЕ СМЕТКА ISI2204260011502
МАРТИНА СВЕТОСЛАВОВА КОВАЛИК
[IBAN]
1 000.00
Общо
588.12
5 325.26
: No sort applied, sorting is disabled
Общо
Дата: No sort applied, activate to apply an ascending sort
▲
ДАТА
▼
04.05.2026
04.05.2026
04.05.2026
04.05.2026
04.05.2026
04.05.2026
04.05.2026
30.04.2026
30.04.2026
22.04.2026
Общо
Основание: No sort applied, activate to apply an ascending sort
▲
ОСНОВАНИЕ
▼
04.05.2026 ПРОФЕСИОНАЛЕН ДОМОУАБ.N. 14044121 НАШИЯТ ВХОД ООД
04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД
04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД
04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД
04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД
04.05.2026 ПРИРОДЕН ГАЗ АБ.N. 1000083763 OVERGAS
ДАНИЕЛ КОВАЛИК МАЙ
ТАКСА ПАКЕТНО ОБСЛУЖВАНЕ
ЗАПЛАТА ЗА МЕСЕЦ 04.2026 OPNAT 0
ЗАХРАНВАНЕ СМЕТКА ISI2204260011502
Общо
Наредител/Получател: No sort applied, activate to apply an ascending sort
▲
НАРЕДИТЕЛ/ПОЛУЧАТЕЛ
▼
КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА
ЧЦДГ МИЛА
ВЕДА ПЕЙРОЛ ООД
МАРТИНА СВЕТОСЛАВОВА КОВАЛИК
Общо
Номер сметка на наредителя / получателя: No sort applied, activate to apply an ascending sort
▲
НОМЕР СМЕТКА НА НАРЕДИТЕЛЯ / ПОЛУЧАТЕЛЯ
▼
[IBAN]
[IBAN]
[IBAN]
[IBAN]
[IBAN]
[IBAN]
[IBAN]
[CREDIT_CARD]
[IBAN]
[IBAN]
Общо
Дебит: No sort applied, activate to apply an ascending sort
▲
ДЕБИТ
▼
17.93
8.44
47.63
0.09
29.54
14.27
460.00
10.22
588.12
Кредит: No sort applied, activate to apply an ascending sort
▲
КРЕДИТ
▼
4 325.26
1 000.00
5 325.26
*Фиксиран курс за целите на двойно обозначение 1 EUR = 1.95583 BGN
Потребителско ръководство - граждани
Потребителско ръководство - граждани
Общи условия за граждани
Общи условия за граждани
Тарифа за граждани
Тарифа за граждани
Call center:
*2375
0700 10 375
Потребителско ръководство - фирми
Потребителско ръководство - фирми
Общи условия за фирми
Общи условия за фирми
Тарифа за фирми
Тарифа за фирми
BIC/SWIFT на Банка ДСК: STSABGSF ©
2026 on DAIS eBank .NET...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"report(2).csv","depth":6,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Completed — 2.6 KB","depth":6,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Show in Finder","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"report(1).csv","depth":6,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Completed — 1.4 KB","depth":6,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Show in Finder","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show all downloads","depth":3,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"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":"Оптичен интернет за дома - EON телевизия | Vivacom | 5G","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Оптичен интернет за дома - EON телевизия | Vivacom | 5G","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":"[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - 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":"[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - kovaliklukas@gmail.com - Gmail","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"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":"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":true},{"role":"AXStaticText","text":"Електронно банкиране ДСК Директ от Банка ДСК","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,"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":"AXStaticText","text":"LUKAS KOVALIK","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 Входяща поща","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Входяща поща","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Обратна връзка","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Обратна връзка","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"English","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"English","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Изход","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Изход","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"СРЕДСТВА","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"СРЕДСТВА","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"КРЕДИТИ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"КРЕДИТИ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"КАРТИ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"КАРТИ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"БИТОВИ СМЕТКИ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"БИТОВИ СМЕТКИ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ПРЕВОДИ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ПРЕВОДИ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"СПЕСТЯВАНЕ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"СПЕСТЯВАНЕ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ФОНДОВЕ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ФОНДОВЕ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ЗАЯВКИ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ЗАЯВКИ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ИЗВЕСТИЯ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ИЗВЕСТИЯ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"СМАРТ ПРИЛОЖЕНИЯ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"СМАРТ ПРИЛОЖЕНИЯ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"НАСТРОЙКИ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"НАСТРОЙКИ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"С какво разполагам","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"С какво разполагам","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Извлечения PDF","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Извлечения PDF","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Извлечения за период / месец","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Извлечения за период / месец","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Движения по сметки","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Движения по сметки","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Справка за IBAN","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Справка за IBAN","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Движения","depth":12,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Движения","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Управление на бърз достъп до менюта.","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":false,"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":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":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":"AXRadioButton","text":"Последните","depth":13,"on_screen":false,"help_text":"","role_description":"radio 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":"AXTextField","text":"10","depth":12,"on_screen":false,"value":"10","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"За период от","depth":13,"on_screen":true,"help_text":"","role_description":"radio 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":"AXTextField","text":"09.05.2026","depth":12,"on_screen":true,"value":"09.05.2026","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"до","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"09.05.2026","depth":12,"on_screen":true,"value":"09.05.2026","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Днес","depth":12,"on_screen":true,"help_text":"","role_description":"link","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":"AXLink","text":"От началото на месеца","depth":12,"on_screen":true,"help_text":"","role_description":"link","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":"AXLink","text":"От началото на годината","depth":12,"on_screen":true,"help_text":"","role_description":"link","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":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":"AXButton","text":"Експорт към файл","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Покажи","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Покажи","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":": No sort applied, sorting is disabled","depth":14,"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXCell","text":"Дата: No sort applied, activate to apply an ascending sort","depth":14,"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ДАТА","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Основание: No sort applied, activate to apply an ascending sort","depth":14,"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ОСНОВАНИЕ","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Наредител/Получател: No sort applied, activate to apply an ascending sort","depth":14,"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"НАРЕДИТЕЛ/ПОЛУЧАТЕЛ","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Номер сметка на наредителя / получателя: No sort applied, activate to apply an ascending sort","depth":14,"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"НОМЕР СМЕТКА НА НАРЕДИТЕЛЯ / ПОЛУЧАТЕЛЯ","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Дебит: No sort applied, activate to apply an ascending sort","depth":14,"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ДЕБИТ","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Кредит: No sort applied, activate to apply an ascending sort","depth":14,"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КРЕДИТ","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 ПРОФЕСИОНАЛЕН ДОМОУАБ.N. 14044121 НАШИЯТ ВХОД ООД","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG91STSA93000004594021","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17.93","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"С0ФИЙСКА ВОДА ДСК ДИРЕКТ","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG03STSA93000045940400","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8.44","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG15STSA93000004594031","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"47.63","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG15STSA93000004594031","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.09","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"С0ФИЙСКА ВОДА ДСК ДИРЕКТ","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG03STSA93000045940400","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"29.54","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 ПРИРОДЕН ГАЗ АБ.N. 1000083763 OVERGAS","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG57STSA93000004594051","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"14.27","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ДАНИЕЛ КОВАЛИК МАЙ","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЧЦДГ МИЛА","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG43UBBS81551007780277","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"460.00","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30.04.2026","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ТАКСА ПАКЕТНО ОБСЛУЖВАНЕ","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7291133030269999","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.22","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30.04.2026","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЗАПЛАТА ЗА МЕСЕЦ 04.2026 OPNAT 0","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ВЕДА ПЕЙРОЛ ООД","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG65UNCR70001525823547","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 325.26","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22.04.2026","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЗАХРАНВАНЕ СМЕТКА ISI2204260011502","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"МАРТИНА СВЕТОСЛАВОВА КОВАЛИК","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG28UNCR70001522249763","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 000.00","depth":16,"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":"588.12","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5 325.26","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":": No sort applied, sorting is disabled","depth":14,"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Общо","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Дата: No sort applied, activate to apply an ascending sort","depth":14,"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ДАТА","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30.04.2026","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30.04.2026","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22.04.2026","depth":15,"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":"AXCell","text":"Основание: No sort applied, activate to apply an ascending sort","depth":14,"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ОСНОВАНИЕ","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 ПРОФЕСИОНАЛЕН ДОМОУАБ.N. 14044121 НАШИЯТ ВХОД ООД","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 ПРИРОДЕН ГАЗ АБ.N. 1000083763 OVERGAS","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ДАНИЕЛ КОВАЛИК МАЙ","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ТАКСА ПАКЕТНО ОБСЛУЖВАНЕ","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЗАПЛАТА ЗА МЕСЕЦ 04.2026 OPNAT 0","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЗАХРАНВАНЕ СМЕТКА ISI2204260011502","depth":16,"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":"AXCell","text":"Наредител/Получател: No sort applied, activate to apply an ascending sort","depth":14,"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"НАРЕДИТЕЛ/ПОЛУЧАТЕЛ","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"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":"С0ФИЙСКА ВОДА ДСК ДИРЕКТ","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"С0ФИЙСКА ВОДА ДСК ДИРЕКТ","depth":15,"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":"ЧЦДГ МИЛА","depth":15,"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":"МАРТИНА СВЕТОСЛАВОВА КОВАЛИК","depth":15,"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":"AXCell","text":"Номер сметка на наредителя / получателя: No sort applied, activate to apply an ascending sort","depth":14,"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"НОМЕР СМЕТКА НА НАРЕДИТЕЛЯ / ПОЛУЧАТЕЛЯ","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG91STSA93000004594021","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG03STSA93000045940400","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG15STSA93000004594031","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG15STSA93000004594031","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG03STSA93000045940400","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG57STSA93000004594051","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG43UBBS81551007780277","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7291133030269999","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG65UNCR70001525823547","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG28UNCR70001522249763","depth":15,"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":"AXCell","text":"Дебит: No sort applied, activate to apply an ascending sort","depth":14,"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ДЕБИТ","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17.93","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8.44","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"47.63","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.09","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"29.54","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"14.27","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"460.00","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.22","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"588.12","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Кредит: No sort applied, activate to apply an ascending sort","depth":14,"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КРЕДИТ","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 325.26","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 000.00","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5 325.26","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*Фиксиран курс за целите на двойно обозначение 1 EUR = 1.95583 BGN","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Потребителско ръководство - граждани","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Потребителско ръководство - граждани","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Общи условия за граждани","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Общи условия за граждани","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Тарифа за граждани","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Тарифа за граждани","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Call center:","depth":13,"bounds":{"left":0.009722223,"top":0.05,"width":0.054166667,"height":0.022777777},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*2375","depth":13,"bounds":{"left":0.072916664,"top":0.05,"width":0.03125,"height":0.022777777},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0700 10 375","depth":13,"bounds":{"left":0.11319444,"top":0.05,"width":0.05659722,"height":0.022777777},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Потребителско ръководство - фирми","depth":13,"bounds":{"left":0.26597223,"top":0.05,"width":0.18229167,"height":0.022777777},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Потребителско ръководство - фирми","depth":14,"bounds":{"left":0.26597223,"top":0.05,"width":0.18229167,"height":0.022777777},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Общи условия за фирми","depth":13,"bounds":{"left":0.29756945,"top":0.08166666,"width":0.119097225,"height":0.022777777},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Общи условия за фирми","depth":14,"bounds":{"left":0.29756945,"top":0.08166666,"width":0.119097225,"height":0.022777777},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Тарифа за фирми","depth":13,"bounds":{"left":0.3142361,"top":0.11333334,"width":0.08576389,"height":0.022777777},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Тарифа за фирми","depth":14,"bounds":{"left":0.3142361,"top":0.11333334,"width":0.08576389,"height":0.022777777},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BIC/SWIFT на Банка ДСК: STSABGSF ©","depth":12,"bounds":{"left":0.0,"top":0.15722223,"width":0.13958333,"height":0.017222222},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026 on DAIS eBank .NET","depth":12,"bounds":{"left":0.11597222,"top":0.15722223,"width":0.08680555,"height":0.017222222},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8252827705313497591
|
-4461283027726564078
|
click
|
accessibility
|
NULL
|
report(2).csv
Completed — 2.6 KB
Show in Finder
re report(2).csv
Completed — 2.6 KB
Show in Finder
report(1).csv
Completed — 1.4 KB
Show in Finder
Show all downloads
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
Оптичен интернет за дома - EON телевизия | Vivacom | 5G
Оптичен интернет за дома - EON телевизия | Vivacom | 5G
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - [EMAIL] - Gmail
[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - [EMAIL] - Gmail
New Tab
New Tab
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Select: payments - db - Adminer
Select: payments - db - Adminer
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
LUKAS KOVALIK
1 Входяща поща
1
Входяща поща
Обратна връзка
Обратна връзка
English
English
Изход
Изход
СРЕДСТВА
СРЕДСТВА
КРЕДИТИ
КРЕДИТИ
КАРТИ
КАРТИ
БИТОВИ СМЕТКИ
БИТОВИ СМЕТКИ
ПРЕВОДИ
ПРЕВОДИ
СПЕСТЯВАНЕ
СПЕСТЯВАНЕ
ФОНДОВЕ
ФОНДОВЕ
ЗАЯВКИ
ЗАЯВКИ
ИЗВЕСТИЯ
ИЗВЕСТИЯ
СМАРТ ПРИЛОЖЕНИЯ
СМАРТ ПРИЛОЖЕНИЯ
НАСТРОЙКИ
НАСТРОЙКИ
С какво разполагам
С какво разполагам
Извлечения PDF
Извлечения PDF
Извлечения за период / месец
Извлечения за период / месец
Движения по сметки
Движения по сметки
Справка за IBAN
Справка за IBAN
Движения
Движения
Управление на бърз достъп до менюта.
Банков клиент
Сметка
Движения
Основание
Отсрещна страна - име
Отсрещна страна - сметка
Последните
Последните
10
За период от
За период от
09.05.2026
до
09.05.2026
Днес
Днес
От началото на месеца
От началото на месеца
От началото на годината
От началото на годината
Сума от
до
Експорт към файл
Покажи
Покажи
: No sort applied, sorting is disabled
Дата: No sort applied, activate to apply an ascending sort
▲
ДАТА
▼
Основание: No sort applied, activate to apply an ascending sort
▲
ОСНОВАНИЕ
▼
Наредител/Получател: No sort applied, activate to apply an ascending sort
▲
НАРЕДИТЕЛ/ПОЛУЧАТЕЛ
▼
Номер сметка на наредителя / получателя: No sort applied, activate to apply an ascending sort
▲
НОМЕР СМЕТКА НА НАРЕДИТЕЛЯ / ПОЛУЧАТЕЛЯ
▼
Дебит: No sort applied, activate to apply an ascending sort
▲
ДЕБИТ
▼
Кредит: No sort applied, activate to apply an ascending sort
▲
КРЕДИТ
▼
04.05.2026
04.05.2026 ПРОФЕСИОНАЛЕН ДОМОУАБ.N. 14044121 НАШИЯТ ВХОД ООД
КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ
[IBAN]
17.93
04.05.2026
04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
[IBAN]
8.44
04.05.2026
04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
[IBAN]
47.63
04.05.2026
04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
[IBAN]
0.09
04.05.2026
04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
[IBAN]
29.54
04.05.2026
04.05.2026 ПРИРОДЕН ГАЗ АБ.N. 1000083763 OVERGAS
ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА
[IBAN]
14.27
04.05.2026
ДАНИЕЛ КОВАЛИК МАЙ
ЧЦДГ МИЛА
[IBAN]
460.00
30.04.2026
ТАКСА ПАКЕТНО ОБСЛУЖВАНЕ
[CREDIT_CARD]
10.22
30.04.2026
ЗАПЛАТА ЗА МЕСЕЦ 04.2026 OPNAT 0
ВЕДА ПЕЙРОЛ ООД
[IBAN]
4 325.26
22.04.2026
ЗАХРАНВАНЕ СМЕТКА ISI2204260011502
МАРТИНА СВЕТОСЛАВОВА КОВАЛИК
[IBAN]
1 000.00
Общо
588.12
5 325.26
: No sort applied, sorting is disabled
Общо
Дата: No sort applied, activate to apply an ascending sort
▲
ДАТА
▼
04.05.2026
04.05.2026
04.05.2026
04.05.2026
04.05.2026
04.05.2026
04.05.2026
30.04.2026
30.04.2026
22.04.2026
Общо
Основание: No sort applied, activate to apply an ascending sort
▲
ОСНОВАНИЕ
▼
04.05.2026 ПРОФЕСИОНАЛЕН ДОМОУАБ.N. 14044121 НАШИЯТ ВХОД ООД
04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД
04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД
04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД
04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД
04.05.2026 ПРИРОДЕН ГАЗ АБ.N. 1000083763 OVERGAS
ДАНИЕЛ КОВАЛИК МАЙ
ТАКСА ПАКЕТНО ОБСЛУЖВАНЕ
ЗАПЛАТА ЗА МЕСЕЦ 04.2026 OPNAT 0
ЗАХРАНВАНЕ СМЕТКА ISI2204260011502
Общо
Наредител/Получател: No sort applied, activate to apply an ascending sort
▲
НАРЕДИТЕЛ/ПОЛУЧАТЕЛ
▼
КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА
ЧЦДГ МИЛА
ВЕДА ПЕЙРОЛ ООД
МАРТИНА СВЕТОСЛАВОВА КОВАЛИК
Общо
Номер сметка на наредителя / получателя: No sort applied, activate to apply an ascending sort
▲
НОМЕР СМЕТКА НА НАРЕДИТЕЛЯ / ПОЛУЧАТЕЛЯ
▼
[IBAN]
[IBAN]
[IBAN]
[IBAN]
[IBAN]
[IBAN]
[IBAN]
[CREDIT_CARD]
[IBAN]
[IBAN]
Общо
Дебит: No sort applied, activate to apply an ascending sort
▲
ДЕБИТ
▼
17.93
8.44
47.63
0.09
29.54
14.27
460.00
10.22
588.12
Кредит: No sort applied, activate to apply an ascending sort
▲
КРЕДИТ
▼
4 325.26
1 000.00
5 325.26
*Фиксиран курс за целите на двойно обозначение 1 EUR = 1.95583 BGN
Потребителско ръководство - граждани
Потребителско ръководство - граждани
Общи условия за граждани
Общи условия за граждани
Тарифа за граждани
Тарифа за граждани
Call center:
*2375
0700 10 375
Потребителско ръководство - фирми
Потребителско ръководство - фирми
Общи условия за фирми
Общи условия за фирми
Тарифа за фирми
Тарифа за фирми
BIC/SWIFT на Банка ДСК: STSABGSF ©
2026 on DAIS eBank .NET...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
11915
|
532
|
0
|
2026-05-09T08:09:11.943349+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778314151943_m2.jpg...
|
Firefox
|
Електронно банкиране ДСК Директ от Банка ДСК — Per Електронно банкиране ДСК Директ от Банка ДСК — Personal...
|
True
|
www.dskdirect.bg/page/default.aspx?user_id=1130906 www.dskdirect.bg/page/default.aspx?user_id=11309067&session_id=51faf0494b7e11f19be7005056b08056ImAgaqvVfd74VO0qZJ2DAOK-Ch6nf7D-q9D0X%2fT5Sa6XCG%2ff8wKZN-T5Tsjny7uz28IzZWLAWXb66J-J4wZTLw%3d%3dU&xml_id=/bg-BG/01Individuals/02Accounts/07Excerpts/&SelectedAccountID=26574472...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
report(2).csv
Completed — 2.6 KB
Show in Finder
re report(2).csv
Completed — 2.6 KB
Show in Finder
report(1).csv
Completed — 1.4 KB
Show in Finder
Show all downloads
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
Оптичен интернет за дома - EON телевизия | Vivacom | 5G
Оптичен интернет за дома - EON телевизия | Vivacom | 5G
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - [EMAIL] - Gmail
[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - [EMAIL] - Gmail
New Tab
New Tab
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Select: payments - db - Adminer
Select: payments - db - Adminer
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
LUKAS KOVALIK
1 Входяща поща
1
Входяща поща
Обратна връзка
Обратна връзка
English
English
Изход
Изход
СРЕДСТВА
СРЕДСТВА
КРЕДИТИ
КРЕДИТИ
КАРТИ
КАРТИ
БИТОВИ СМЕТКИ
БИТОВИ СМЕТКИ
ПРЕВОДИ
ПРЕВОДИ
СПЕСТЯВАНЕ
СПЕСТЯВАНЕ
ФОНДОВЕ
ФОНДОВЕ
ЗАЯВКИ
ЗАЯВКИ
ИЗВЕСТИЯ
ИЗВЕСТИЯ
СМАРТ ПРИЛОЖЕНИЯ
СМАРТ ПРИЛОЖЕНИЯ
НАСТРОЙКИ
НАСТРОЙКИ
С какво разполагам
С какво разполагам
Извлечения PDF
Извлечения PDF
Извлечения за период / месец
Извлечения за период / месец
Движения по сметки
Движения по сметки
Справка за IBAN
Справка за IBAN
Движения
Движения
Управление на бърз достъп до менюта.
Банков клиент
Сметка
Движения
Основание
Отсрещна страна - име
Отсрещна страна - сметка
Последните
Последните
10
За период от
За период от
09.05.2026
до
09.05.2026
Днес
Днес
От началото на месеца
От началото на месеца
От началото на годината
От началото на годината
Сума от
до
Експорт към файл
Покажи
Покажи
: No sort applied, sorting is disabled
Дата: No sort applied, activate to apply an ascending sort
▲
ДАТА
▼
Основание: No sort applied, activate to apply an ascending sort
▲
ОСНОВАНИЕ
▼
Наредител/Получател: No sort applied, activate to apply an ascending sort
▲
НАРЕДИТЕЛ/ПОЛУЧАТЕЛ
▼
Номер сметка на наредителя / получателя: No sort applied, activate to apply an ascending sort
▲
НОМЕР СМЕТКА НА НАРЕДИТЕЛЯ / ПОЛУЧАТЕЛЯ
▼
Дебит: No sort applied, activate to apply an ascending sort
▲
ДЕБИТ
▼
Кредит: No sort applied, activate to apply an ascending sort
▲
КРЕДИТ
▼
04.05.2026
04.05.2026 ПРОФЕСИОНАЛЕН ДОМОУАБ.N. 14044121 НАШИЯТ ВХОД ООД
КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ
[IBAN]
17.93
04.05.2026
04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
[IBAN]
8.44
04.05.2026
04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
[IBAN]
47.63
04.05.2026
04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
[IBAN]
0.09
04.05.2026
04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
[IBAN]
29.54
04.05.2026
04.05.2026 ПРИРОДЕН ГАЗ АБ.N. 1000083763 OVERGAS
ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА
[IBAN]
14.27
04.05.2026
ДАНИЕЛ КОВАЛИК МАЙ
ЧЦДГ МИЛА
[IBAN]
460.00
30.04.2026
ТАКСА ПАКЕТНО ОБСЛУЖВАНЕ
[CREDIT_CARD]
10.22
30.04.2026
ЗАПЛАТА ЗА МЕСЕЦ 04.2026 OPNAT 0
ВЕДА ПЕЙРОЛ ООД
[IBAN]
4 325.26
22.04.2026
ЗАХРАНВАНЕ СМЕТКА ISI2204260011502
МАРТИНА СВЕТОСЛАВОВА КОВАЛИК
[IBAN]
1 000.00
Общо
588.12
5 325.26
: No sort applied, sorting is disabled
Общо
Дата: No sort applied, activate to apply an ascending sort
▲
ДАТА
▼
04.05.2026
04.05.2026
04.05.2026
04.05.2026
04.05.2026
04.05.2026
04.05.2026
30.04.2026
30.04.2026
22.04.2026
Общо
Основание: No sort applied, activate to apply an ascending sort
▲
ОСНОВАНИЕ
▼
04.05.2026 ПРОФЕСИОНАЛЕН ДОМОУАБ.N. 14044121 НАШИЯТ ВХОД ООД
04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД
04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД
04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД
04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД
04.05.2026 ПРИРОДЕН ГАЗ АБ.N. 1000083763 OVERGAS
ДАНИЕЛ КОВАЛИК МАЙ
ТАКСА ПАКЕТНО ОБСЛУЖВАНЕ
ЗАПЛАТА ЗА МЕСЕЦ 04.2026 OPNAT 0
ЗАХРАНВАНЕ СМЕТКА ISI2204260011502
Общо
Наредител/Получател: No sort applied, activate to apply an ascending sort
▲
НАРЕДИТЕЛ/ПОЛУЧАТЕЛ
▼
КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА
ЧЦДГ МИЛА
ВЕДА ПЕЙРОЛ ООД
МАРТИНА СВЕТОСЛАВОВА КОВАЛИК
Общо
Номер сметка на наредителя / получателя: No sort applied, activate to apply an ascending sort
▲
НОМЕР СМЕТКА НА НАРЕДИТЕЛЯ / ПОЛУЧАТЕЛЯ
▼
[IBAN]
[IBAN]
[IBAN]
[IBAN]
[IBAN]
[IBAN]
[IBAN]
[CREDIT_CARD]
[IBAN]
[IBAN]
Общо
Дебит: No sort applied, activate to apply an ascending sort
▲
ДЕБИТ
▼
17.93
8.44
47.63
0.09
29.54
14.27
460.00
10.22
588.12
Кредит: No sort applied, activate to apply an ascending sort
▲
КРЕДИТ
▼
4 325.26
1 000.00
5 325.26
*Фиксиран курс за целите на двойно обозначение 1 EUR = 1.95583 BGN
Потребителско ръководство - граждани
Потребителско ръководство - граждани
Общи условия за граждани
Общи условия за граждани
Тарифа за граждани
Тарифа за граждани
Call center:
*2375
0700 10 375
Потребителско ръководство - фирми
Потребителско ръководство - фирми
Общи условия за фирми
Общи условия за фирми
Тарифа за фирми
Тарифа за фирми
BIC/SWIFT на Банка ДСК: STSABGSF ©
2026 on DAIS eBank .NET...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"report(2).csv","depth":6,"bounds":{"left":0.28158244,"top":0.0622506,"width":0.026263298,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Completed — 2.6 KB","depth":6,"bounds":{"left":0.28158244,"top":0.07821229,"width":0.033909574,"height":0.0103751},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Show in Finder","depth":5,"bounds":{"left":0.40924203,"top":0.06384677,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"report(1).csv","depth":6,"bounds":{"left":0.28158244,"top":0.10973663,"width":0.025598405,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Completed — 1.4 KB","depth":6,"bounds":{"left":0.28158244,"top":0.12569833,"width":0.03357713,"height":0.0103751},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Show in Finder","depth":5,"bounds":{"left":0.40924203,"top":0.111332804,"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":"Show all downloads","depth":3,"bounds":{"left":0.26662233,"top":0.15163608,"width":0.15458776,"height":0.027134877},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"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":"Оптичен интернет за дома - EON телевизия | Vivacom | 5G","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":"Оптичен интернет за дома - EON телевизия | Vivacom | 5G","depth":5,"bounds":{"left":0.013297873,"top":0.32482043,"width":0.105884306,"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.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":"AFFiNE - All In One KnowledgeOS","depth":5,"bounds":{"left":0.013297873,"top":0.3575419,"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.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":"All docs · AFFiNE","depth":5,"bounds":{"left":0.013297873,"top":0.39026338,"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.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":"Payments Logger","depth":5,"bounds":{"left":0.013297873,"top":0.42298484,"width":0.030086435,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - kovaliklukas@gmail.com - Gmail","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":"[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - kovaliklukas@gmail.com - Gmail","depth":5,"bounds":{"left":0.013297873,"top":0.4557063,"width":0.22639628,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","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":"New Tab","depth":5,"bounds":{"left":0.013297873,"top":0.4884278,"width":0.014960106,"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.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":"Location Logger","depth":5,"bounds":{"left":0.013297873,"top":0.5211492,"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.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":false},{"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":"AXRadioButton","text":"Finance Hub","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":"Finance Hub","depth":5,"bounds":{"left":0.013297873,"top":0.5865922,"width":0.021609042,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Select: payments - db - Adminer","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":"Select: payments - db - Adminer","depth":5,"bounds":{"left":0.013297873,"top":0.61931366,"width":0.05651596,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Електронно банкиране ДСК Директ от Банка ДСК","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":true},{"role":"AXStaticText","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":5,"bounds":{"left":0.013297873,"top":0.6520351,"width":0.09059176,"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.6480447,"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.0028257978,"top":0.67517954,"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":"AXStaticText","text":"LUKAS KOVALIK","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 Входяща поща","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Входяща поща","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Обратна връзка","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Обратна връзка","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"English","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"English","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Изход","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Изход","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"СРЕДСТВА","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"СРЕДСТВА","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"КРЕДИТИ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"КРЕДИТИ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"КАРТИ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"КАРТИ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"БИТОВИ СМЕТКИ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"БИТОВИ СМЕТКИ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ПРЕВОДИ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ПРЕВОДИ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"СПЕСТЯВАНЕ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"СПЕСТЯВАНЕ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ФОНДОВЕ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ФОНДОВЕ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ЗАЯВКИ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ЗАЯВКИ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ИЗВЕСТИЯ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ИЗВЕСТИЯ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"СМАРТ ПРИЛОЖЕНИЯ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"СМАРТ ПРИЛОЖЕНИЯ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"НАСТРОЙКИ","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"НАСТРОЙКИ","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"С какво разполагам","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"С какво разполагам","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Извлечения PDF","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Извлечения PDF","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Извлечения за период / месец","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Извлечения за период / месец","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Движения по сметки","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Движения по сметки","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Справка за IBAN","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Справка за IBAN","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Движения","depth":12,"bounds":{"left":0.12367021,"top":0.0,"width":0.027759308,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Движения","depth":13,"bounds":{"left":0.12367021,"top":0.002793296,"width":0.027759308,"height":0.018355945},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Управление на бърз достъп до менюта.","depth":13,"bounds":{"left":0.15142952,"top":0.0,"width":0.021276595,"height":0.031923383},"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.13397606,"top":0.0,"width":0.03025266,"height":0.014365523},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Сметка","depth":13,"bounds":{"left":0.13397606,"top":0.027134877,"width":0.01462766,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Движения","depth":13,"bounds":{"left":0.13397606,"top":0.05905826,"width":0.021110373,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Основание","depth":13,"bounds":{"left":0.13397606,"top":0.09098165,"width":0.022606382,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Отсрещна страна - име","depth":13,"bounds":{"left":0.13397606,"top":0.11811652,"width":0.03557181,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Отсрещна страна - сметка","depth":13,"bounds":{"left":0.13397606,"top":0.15482841,"width":0.03557181,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Последните","depth":13,"bounds":{"left":0.3181516,"top":0.0,"width":0.004654255,"height":0.011173184},"on_screen":false,"help_text":"","role_description":"radio button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Последните","depth":13,"bounds":{"left":0.32613033,"top":0.0,"width":0.024601065,"height":0.014365523},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"10","depth":12,"bounds":{"left":0.3693484,"top":0.0,"width":0.03656915,"height":0.023942538},"on_screen":false,"value":"10","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"За период от","depth":13,"bounds":{"left":0.3181516,"top":0.028731046,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"radio button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"За период от","depth":13,"bounds":{"left":0.32613033,"top":0.027134877,"width":0.02642952,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"09.05.2026","depth":12,"bounds":{"left":0.3693484,"top":0.022346368,"width":0.03656915,"height":0.023942538},"on_screen":true,"value":"09.05.2026","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"до","depth":13,"bounds":{"left":0.4085771,"top":0.027134877,"width":0.004986702,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"09.05.2026","depth":12,"bounds":{"left":0.41722074,"top":0.022346368,"width":0.03656915,"height":0.023942538},"on_screen":true,"value":"09.05.2026","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Днес","depth":12,"bounds":{"left":0.31648937,"top":0.054269753,"width":0.020611702,"height":0.023942538},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Днес","depth":13,"bounds":{"left":0.32214096,"top":0.060654428,"width":0.009973404,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"От началото на месеца","depth":12,"bounds":{"left":0.33710107,"top":0.054269753,"width":0.057347074,"height":0.023942538},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"От началото на месеца","depth":13,"bounds":{"left":0.34275267,"top":0.060654428,"width":0.046708778,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"От началото на годината","depth":12,"bounds":{"left":0.39444813,"top":0.054269753,"width":0.06216755,"height":0.023942538},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"От началото на годината","depth":13,"bounds":{"left":0.40009972,"top":0.060654428,"width":0.05086436,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Сума от","depth":13,"bounds":{"left":0.3181516,"top":0.09098165,"width":0.015625,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"до","depth":13,"bounds":{"left":0.39727393,"top":0.09098165,"width":0.004986702,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Експорт към файл","depth":12,"bounds":{"left":0.36801863,"top":0.20510775,"width":0.05718085,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Покажи","depth":11,"bounds":{"left":0.43018618,"top":0.20510775,"width":0.031416222,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Покажи","depth":12,"bounds":{"left":0.4368351,"top":0.21308859,"width":0.018118352,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":": No sort applied, sorting is disabled","depth":14,"bounds":{"left":0.13464096,"top":0.3008779,"width":0.008976064,"height":0.056264963},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXCell","text":"Дата: No sort applied, activate to apply an ascending sort","depth":14,"bounds":{"left":0.14361702,"top":0.3008779,"width":0.027426861,"height":0.056264963},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"bounds":{"left":0.16505983,"top":0.3320032,"width":0.0026595744,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ДАТА","depth":16,"bounds":{"left":0.14694148,"top":0.33359936,"width":0.009973404,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"bounds":{"left":0.16505983,"top":0.33838788,"width":0.0026595744,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Основание: No sort applied, activate to apply an ascending sort","depth":14,"bounds":{"left":0.17104389,"top":0.3008779,"width":0.116023935,"height":0.056264963},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"bounds":{"left":0.28108376,"top":0.3320032,"width":0.0026595744,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ОСНОВАНИЕ","depth":16,"bounds":{"left":0.17436835,"top":0.33359936,"width":0.025099734,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"bounds":{"left":0.28108376,"top":0.33838788,"width":0.0026595744,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Наредител/Получател: No sort applied, activate to apply an ascending sort","depth":14,"bounds":{"left":0.28706783,"top":0.3008779,"width":0.094913565,"height":0.056264963},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"bounds":{"left":0.37583113,"top":0.3320032,"width":0.0028257978,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"НАРЕДИТЕЛ/ПОЛУЧАТЕЛ","depth":16,"bounds":{"left":0.29039228,"top":0.33359936,"width":0.049534574,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"bounds":{"left":0.37583113,"top":0.33838788,"width":0.0028257978,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Номер сметка на наредителя / получателя: No sort applied, activate to apply an ascending sort","depth":14,"bounds":{"left":0.38198137,"top":0.3008779,"width":0.06050532,"height":0.056264963},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"bounds":{"left":0.43633643,"top":0.3320032,"width":0.0028257978,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"НОМЕР СМЕТКА НА НАРЕДИТЕЛЯ / ПОЛУЧАТЕЛЯ","depth":16,"bounds":{"left":0.38530585,"top":0.30885875,"width":0.037732713,"height":0.037110932},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"bounds":{"left":0.43633643,"top":0.33838788,"width":0.0028257978,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Дебит: No sort applied, activate to apply an ascending sort","depth":14,"bounds":{"left":0.4424867,"top":0.3008779,"width":0.024933511,"height":0.056264963},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"bounds":{"left":0.46143618,"top":0.3320032,"width":0.0026595744,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ДЕБИТ","depth":16,"bounds":{"left":0.44581118,"top":0.33359936,"width":0.013297873,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"bounds":{"left":0.46143618,"top":0.33838788,"width":0.0026595744,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Кредит: No sort applied, activate to apply an ascending sort","depth":14,"bounds":{"left":0.46742022,"top":0.3008779,"width":0.024268618,"height":0.056264963},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"bounds":{"left":0.48902926,"top":0.3320032,"width":0.0026595744,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КРЕДИТ","depth":16,"bounds":{"left":0.47074467,"top":0.33359936,"width":0.015957447,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"bounds":{"left":0.48902926,"top":0.33838788,"width":0.0026595744,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":16,"bounds":{"left":0.14694148,"top":0.37390262,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 ПРОФЕСИОНАЛЕН ДОМОУАБ.N. 14044121 НАШИЯТ ВХОД ООД","depth":17,"bounds":{"left":0.17436835,"top":0.36671987,"width":0.10472074,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ","depth":16,"bounds":{"left":0.29039228,"top":0.37390262,"width":0.07114362,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG91STSA93000004594021","depth":16,"bounds":{"left":0.38530585,"top":0.37390262,"width":0.05219415,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17.93","depth":16,"bounds":{"left":0.45295876,"top":0.37390262,"width":0.011136968,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":16,"bounds":{"left":0.14694148,"top":0.42019153,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД","depth":17,"bounds":{"left":0.17436835,"top":0.41300878,"width":0.08759973,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"С0ФИЙСКА ВОДА ДСК ДИРЕКТ","depth":16,"bounds":{"left":0.29039228,"top":0.42019153,"width":0.06100399,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG03STSA93000045940400","depth":16,"bounds":{"left":0.38530585,"top":0.42019153,"width":0.05219415,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8.44","depth":16,"bounds":{"left":0.4552859,"top":0.42019153,"width":0.00880984,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":16,"bounds":{"left":0.14694148,"top":0.46648043,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД","depth":17,"bounds":{"left":0.17436835,"top":0.4592977,"width":0.08693484,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ","depth":16,"bounds":{"left":0.29039228,"top":0.4592977,"width":0.0809508,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG15STSA93000004594031","depth":16,"bounds":{"left":0.38530585,"top":0.46648043,"width":0.05219415,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"47.63","depth":16,"bounds":{"left":0.45295876,"top":0.46648043,"width":0.011136968,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":16,"bounds":{"left":0.14694148,"top":0.51276934,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД","depth":17,"bounds":{"left":0.17436835,"top":0.50558656,"width":0.08693484,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ","depth":16,"bounds":{"left":0.29039228,"top":0.50558656,"width":0.0809508,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG15STSA93000004594031","depth":16,"bounds":{"left":0.38530585,"top":0.51276934,"width":0.05219415,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.09","depth":16,"bounds":{"left":0.4552859,"top":0.51276934,"width":0.00880984,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":16,"bounds":{"left":0.14694148,"top":0.55905825,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД","depth":17,"bounds":{"left":0.17436835,"top":0.5518755,"width":0.08759973,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"С0ФИЙСКА ВОДА ДСК ДИРЕКТ","depth":16,"bounds":{"left":0.29039228,"top":0.55905825,"width":0.06100399,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG03STSA93000045940400","depth":16,"bounds":{"left":0.38530585,"top":0.55905825,"width":0.05219415,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"29.54","depth":16,"bounds":{"left":0.45295876,"top":0.55905825,"width":0.011136968,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":16,"bounds":{"left":0.14694148,"top":0.60534716,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 ПРИРОДЕН ГАЗ АБ.N. 1000083763 OVERGAS","depth":17,"bounds":{"left":0.17436835,"top":0.60534716,"width":0.107380316,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА","depth":16,"bounds":{"left":0.29039228,"top":0.5981644,"width":0.0852726,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG57STSA93000004594051","depth":16,"bounds":{"left":0.38530585,"top":0.60534716,"width":0.05219415,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"14.27","depth":16,"bounds":{"left":0.45295876,"top":0.60534716,"width":0.011136968,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":16,"bounds":{"left":0.14694148,"top":0.6480447,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ДАНИЕЛ КОВАЛИК МАЙ","depth":17,"bounds":{"left":0.17436835,"top":0.6480447,"width":0.047539894,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЧЦДГ МИЛА","depth":16,"bounds":{"left":0.29039228,"top":0.6480447,"width":0.024102394,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG43UBBS81551007780277","depth":16,"bounds":{"left":0.38530585,"top":0.6480447,"width":0.053357713,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"460.00","depth":16,"bounds":{"left":0.4504654,"top":0.6480447,"width":0.013630319,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30.04.2026","depth":16,"bounds":{"left":0.14694148,"top":0.68715084,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ТАКСА ПАКЕТНО ОБСЛУЖВАНЕ","depth":17,"bounds":{"left":0.17436835,"top":0.68715084,"width":0.06216755,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7291133030269999","depth":16,"bounds":{"left":0.38530585,"top":0.68715084,"width":0.036901597,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.22","depth":16,"bounds":{"left":0.45295876,"top":0.68715084,"width":0.011136968,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30.04.2026","depth":16,"bounds":{"left":0.14694148,"top":0.72625697,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЗАПЛАТА ЗА МЕСЕЦ 04.2026 OPNAT 0","depth":17,"bounds":{"left":0.17436835,"top":0.72625697,"width":0.07280585,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ВЕДА ПЕЙРОЛ ООД","depth":16,"bounds":{"left":0.29039228,"top":0.72625697,"width":0.03873005,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG65UNCR70001525823547","depth":16,"bounds":{"left":0.38530585,"top":0.72625697,"width":0.053856384,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 325.26","depth":16,"bounds":{"left":0.4742354,"top":0.72625697,"width":0.017121011,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22.04.2026","depth":16,"bounds":{"left":0.14694148,"top":0.76536316,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЗАХРАНВАНЕ СМЕТКА ISI2204260011502","depth":17,"bounds":{"left":0.17436835,"top":0.76536316,"width":0.079288565,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"МАРТИНА СВЕТОСЛАВОВА КОВАЛИК","depth":16,"bounds":{"left":0.29039228,"top":0.76536316,"width":0.073803194,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG28UNCR70001522249763","depth":16,"bounds":{"left":0.38530585,"top":0.76536316,"width":0.053856384,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 000.00","depth":16,"bounds":{"left":0.4742354,"top":0.76536316,"width":0.017121011,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Общо","depth":15,"bounds":{"left":0.42519948,"top":0.8028731,"width":0.013962766,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"588.12","depth":15,"bounds":{"left":0.4476396,"top":0.8028731,"width":0.016456118,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5 325.26","depth":15,"bounds":{"left":0.4709109,"top":0.8028731,"width":0.02044548,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":": No sort applied, sorting is disabled","depth":14,"bounds":{"left":0.13464096,"top":0.3008779,"width":0.008976064,"height":0.056264963},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Общо","depth":15,"bounds":{"left":0.42519948,"top":0.8028731,"width":0.013962766,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Дата: No sort applied, activate to apply an ascending sort","depth":14,"bounds":{"left":0.14361702,"top":0.3008779,"width":0.027426861,"height":0.056264963},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"bounds":{"left":0.16505983,"top":0.3320032,"width":0.0026595744,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ДАТА","depth":16,"bounds":{"left":0.14694148,"top":0.33359936,"width":0.009973404,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"bounds":{"left":0.16505983,"top":0.33838788,"width":0.0026595744,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":15,"bounds":{"left":0.14694148,"top":0.37390262,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":15,"bounds":{"left":0.14694148,"top":0.42019153,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":15,"bounds":{"left":0.14694148,"top":0.46648043,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":15,"bounds":{"left":0.14694148,"top":0.51276934,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":15,"bounds":{"left":0.14694148,"top":0.55905825,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":15,"bounds":{"left":0.14694148,"top":0.60534716,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026","depth":15,"bounds":{"left":0.14694148,"top":0.6480447,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30.04.2026","depth":15,"bounds":{"left":0.14694148,"top":0.68715084,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30.04.2026","depth":15,"bounds":{"left":0.14694148,"top":0.72625697,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22.04.2026","depth":15,"bounds":{"left":0.14694148,"top":0.76536316,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Общо","depth":15,"bounds":{"left":0.42519948,"top":0.8028731,"width":0.013962766,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Основание: No sort applied, activate to apply an ascending sort","depth":14,"bounds":{"left":0.17104389,"top":0.3008779,"width":0.116023935,"height":0.056264963},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"bounds":{"left":0.28108376,"top":0.3320032,"width":0.0026595744,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ОСНОВАНИЕ","depth":16,"bounds":{"left":0.17436835,"top":0.33359936,"width":0.025099734,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"bounds":{"left":0.28108376,"top":0.33838788,"width":0.0026595744,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 ПРОФЕСИОНАЛЕН ДОМОУАБ.N. 14044121 НАШИЯТ ВХОД ООД","depth":16,"bounds":{"left":0.17436835,"top":0.36671987,"width":0.10472074,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД","depth":16,"bounds":{"left":0.17436835,"top":0.41300878,"width":0.08759973,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД","depth":16,"bounds":{"left":0.17436835,"top":0.4592977,"width":0.08693484,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД","depth":16,"bounds":{"left":0.17436835,"top":0.50558656,"width":0.08693484,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД","depth":16,"bounds":{"left":0.17436835,"top":0.5518755,"width":0.08759973,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04.05.2026 ПРИРОДЕН ГАЗ АБ.N. 1000083763 OVERGAS","depth":16,"bounds":{"left":0.17436835,"top":0.60534716,"width":0.107380316,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ДАНИЕЛ КОВАЛИК МАЙ","depth":16,"bounds":{"left":0.17436835,"top":0.6480447,"width":0.047539894,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ТАКСА ПАКЕТНО ОБСЛУЖВАНЕ","depth":16,"bounds":{"left":0.17436835,"top":0.68715084,"width":0.06216755,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЗАПЛАТА ЗА МЕСЕЦ 04.2026 OPNAT 0","depth":16,"bounds":{"left":0.17436835,"top":0.72625697,"width":0.07280585,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЗАХРАНВАНЕ СМЕТКА ISI2204260011502","depth":16,"bounds":{"left":0.17436835,"top":0.76536316,"width":0.079288565,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Общо","depth":15,"bounds":{"left":0.42519948,"top":0.8028731,"width":0.013962766,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Наредител/Получател: No sort applied, activate to apply an ascending sort","depth":14,"bounds":{"left":0.28706783,"top":0.3008779,"width":0.094913565,"height":0.056264963},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"bounds":{"left":0.37583113,"top":0.3320032,"width":0.0028257978,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"НАРЕДИТЕЛ/ПОЛУЧАТЕЛ","depth":16,"bounds":{"left":0.29039228,"top":0.33359936,"width":0.049534574,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"bounds":{"left":0.37583113,"top":0.33838788,"width":0.0028257978,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ","depth":15,"bounds":{"left":0.29039228,"top":0.37390262,"width":0.07114362,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"С0ФИЙСКА ВОДА ДСК ДИРЕКТ","depth":15,"bounds":{"left":0.29039228,"top":0.42019153,"width":0.06100399,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ","depth":15,"bounds":{"left":0.29039228,"top":0.4592977,"width":0.0809508,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ","depth":15,"bounds":{"left":0.29039228,"top":0.50558656,"width":0.0809508,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"С0ФИЙСКА ВОДА ДСК ДИРЕКТ","depth":15,"bounds":{"left":0.29039228,"top":0.55905825,"width":0.06100399,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА","depth":15,"bounds":{"left":0.29039228,"top":0.5981644,"width":0.0852726,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЧЦДГ МИЛА","depth":15,"bounds":{"left":0.29039228,"top":0.6480447,"width":0.024102394,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ВЕДА ПЕЙРОЛ ООД","depth":15,"bounds":{"left":0.29039228,"top":0.72625697,"width":0.03873005,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"МАРТИНА СВЕТОСЛАВОВА КОВАЛИК","depth":15,"bounds":{"left":0.29039228,"top":0.76536316,"width":0.073803194,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Общо","depth":15,"bounds":{"left":0.42519948,"top":0.8028731,"width":0.013962766,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Номер сметка на наредителя / получателя: No sort applied, activate to apply an ascending sort","depth":14,"bounds":{"left":0.38198137,"top":0.3008779,"width":0.06050532,"height":0.056264963},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"bounds":{"left":0.43633643,"top":0.3320032,"width":0.0028257978,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"НОМЕР СМЕТКА НА НАРЕДИТЕЛЯ / ПОЛУЧАТЕЛЯ","depth":16,"bounds":{"left":0.38530585,"top":0.30885875,"width":0.037732713,"height":0.037110932},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"bounds":{"left":0.43633643,"top":0.33838788,"width":0.0028257978,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG91STSA93000004594021","depth":15,"bounds":{"left":0.38530585,"top":0.37390262,"width":0.05219415,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG03STSA93000045940400","depth":15,"bounds":{"left":0.38530585,"top":0.42019153,"width":0.05219415,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG15STSA93000004594031","depth":15,"bounds":{"left":0.38530585,"top":0.46648043,"width":0.05219415,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG15STSA93000004594031","depth":15,"bounds":{"left":0.38530585,"top":0.51276934,"width":0.05219415,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG03STSA93000045940400","depth":15,"bounds":{"left":0.38530585,"top":0.55905825,"width":0.05219415,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG57STSA93000004594051","depth":15,"bounds":{"left":0.38530585,"top":0.60534716,"width":0.05219415,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG43UBBS81551007780277","depth":15,"bounds":{"left":0.38530585,"top":0.6480447,"width":0.053357713,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7291133030269999","depth":15,"bounds":{"left":0.38530585,"top":0.68715084,"width":0.036901597,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG65UNCR70001525823547","depth":15,"bounds":{"left":0.38530585,"top":0.72625697,"width":0.053856384,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG28UNCR70001522249763","depth":15,"bounds":{"left":0.38530585,"top":0.76536316,"width":0.053856384,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Общо","depth":15,"bounds":{"left":0.42519948,"top":0.8028731,"width":0.013962766,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Дебит: No sort applied, activate to apply an ascending sort","depth":14,"bounds":{"left":0.4424867,"top":0.3008779,"width":0.024933511,"height":0.056264963},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"bounds":{"left":0.46143618,"top":0.3320032,"width":0.0026595744,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ДЕБИТ","depth":16,"bounds":{"left":0.44581118,"top":0.33359936,"width":0.013297873,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"bounds":{"left":0.46143618,"top":0.33838788,"width":0.0026595744,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17.93","depth":15,"bounds":{"left":0.45295876,"top":0.37390262,"width":0.011136968,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8.44","depth":15,"bounds":{"left":0.4552859,"top":0.42019153,"width":0.00880984,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"47.63","depth":15,"bounds":{"left":0.45295876,"top":0.46648043,"width":0.011136968,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.09","depth":15,"bounds":{"left":0.4552859,"top":0.51276934,"width":0.00880984,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"29.54","depth":15,"bounds":{"left":0.45295876,"top":0.55905825,"width":0.011136968,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"14.27","depth":15,"bounds":{"left":0.45295876,"top":0.60534716,"width":0.011136968,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"460.00","depth":15,"bounds":{"left":0.4504654,"top":0.6480447,"width":0.013630319,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.22","depth":15,"bounds":{"left":0.45295876,"top":0.68715084,"width":0.011136968,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"588.12","depth":15,"bounds":{"left":0.4476396,"top":0.8028731,"width":0.016456118,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Кредит: No sort applied, activate to apply an ascending sort","depth":14,"bounds":{"left":0.46742022,"top":0.3008779,"width":0.024268618,"height":0.056264963},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▲","depth":16,"bounds":{"left":0.48902926,"top":0.3320032,"width":0.0026595744,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КРЕДИТ","depth":16,"bounds":{"left":0.47074467,"top":0.33359936,"width":0.015957447,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▼","depth":16,"bounds":{"left":0.48902926,"top":0.33838788,"width":0.0026595744,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 325.26","depth":15,"bounds":{"left":0.4742354,"top":0.72625697,"width":0.017121011,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 000.00","depth":15,"bounds":{"left":0.4742354,"top":0.76536316,"width":0.017121011,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5 325.26","depth":15,"bounds":{"left":0.4709109,"top":0.8028731,"width":0.02044548,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*Фиксиран курс за целите на двойно обозначение 1 EUR = 1.95583 BGN","depth":12,"bounds":{"left":0.13098404,"top":0.8830806,"width":0.16456117,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Потребителско ръководство - граждани","depth":13,"bounds":{"left":0.13813165,"top":1.0,"width":0.09391622,"height":-0.035913825},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Потребителско ръководство - граждани","depth":14,"bounds":{"left":0.13813165,"top":1.0,"width":0.09391622,"height":-0.035913825},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Общи условия за граждани","depth":13,"bounds":{"left":0.15309176,"top":1.0,"width":0.06382979,"height":-0.058659196},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Общи условия за граждани","depth":14,"bounds":{"left":0.15309176,"top":1.0,"width":0.06382979,"height":-0.058659196},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Тарифа за граждани","depth":13,"bounds":{"left":0.16107048,"top":1.0,"width":0.047872342,"height":-0.081404686},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Тарифа за граждани","depth":14,"bounds":{"left":0.16107048,"top":1.0,"width":0.047872342,"height":-0.081404686},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Call center:","depth":13,"bounds":{"left":0.27493352,"top":1.0,"width":0.025930852,"height":-0.035913825},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*2375","depth":13,"bounds":{"left":0.30518618,"top":1.0,"width":0.014960106,"height":-0.035913825},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0700 10 375","depth":13,"bounds":{"left":0.32446808,"top":1.0,"width":0.027094414,"height":-0.035913825},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Потребителско ръководство - фирми","depth":13,"bounds":{"left":0.39760637,"top":1.0,"width":0.08726729,"height":-0.035913825},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Потребителско ръководство - фирми","depth":14,"bounds":{"left":0.39760637,"top":1.0,"width":0.08726729,"height":-0.035913825},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Общи условия за фирми","depth":13,"bounds":{"left":0.41273272,"top":1.0,"width":0.05701463,"height":-0.058659196},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Общи условия за фирми","depth":14,"bounds":{"left":0.41273272,"top":1.0,"width":0.05701463,"height":-0.058659196},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Тарифа за фирми","depth":13,"bounds":{"left":0.42071143,"top":1.0,"width":0.04105718,"height":-0.081404686},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Тарифа за фирми","depth":14,"bounds":{"left":0.42071143,"top":1.0,"width":0.04105718,"height":-0.081404686},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BIC/SWIFT на Банка ДСК: STSABGSF ©","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026 on DAIS eBank .NET","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8252827705313497591
|
-4461283027726564078
|
manual
|
accessibility
|
NULL
|
report(2).csv
Completed — 2.6 KB
Show in Finder
re report(2).csv
Completed — 2.6 KB
Show in Finder
report(1).csv
Completed — 1.4 KB
Show in Finder
Show all downloads
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
Оптичен интернет за дома - EON телевизия | Vivacom | 5G
Оптичен интернет за дома - EON телевизия | Vivacom | 5G
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - [EMAIL] - Gmail
[NirDiamant/GenAI_Agents] Add SwarmScore — Portable Trust Rating for AI Agents (Issue #115) - [EMAIL] - Gmail
New Tab
New Tab
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Select: payments - db - Adminer
Select: payments - db - Adminer
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
LUKAS KOVALIK
1 Входяща поща
1
Входяща поща
Обратна връзка
Обратна връзка
English
English
Изход
Изход
СРЕДСТВА
СРЕДСТВА
КРЕДИТИ
КРЕДИТИ
КАРТИ
КАРТИ
БИТОВИ СМЕТКИ
БИТОВИ СМЕТКИ
ПРЕВОДИ
ПРЕВОДИ
СПЕСТЯВАНЕ
СПЕСТЯВАНЕ
ФОНДОВЕ
ФОНДОВЕ
ЗАЯВКИ
ЗАЯВКИ
ИЗВЕСТИЯ
ИЗВЕСТИЯ
СМАРТ ПРИЛОЖЕНИЯ
СМАРТ ПРИЛОЖЕНИЯ
НАСТРОЙКИ
НАСТРОЙКИ
С какво разполагам
С какво разполагам
Извлечения PDF
Извлечения PDF
Извлечения за период / месец
Извлечения за период / месец
Движения по сметки
Движения по сметки
Справка за IBAN
Справка за IBAN
Движения
Движения
Управление на бърз достъп до менюта.
Банков клиент
Сметка
Движения
Основание
Отсрещна страна - име
Отсрещна страна - сметка
Последните
Последните
10
За период от
За период от
09.05.2026
до
09.05.2026
Днес
Днес
От началото на месеца
От началото на месеца
От началото на годината
От началото на годината
Сума от
до
Експорт към файл
Покажи
Покажи
: No sort applied, sorting is disabled
Дата: No sort applied, activate to apply an ascending sort
▲
ДАТА
▼
Основание: No sort applied, activate to apply an ascending sort
▲
ОСНОВАНИЕ
▼
Наредител/Получател: No sort applied, activate to apply an ascending sort
▲
НАРЕДИТЕЛ/ПОЛУЧАТЕЛ
▼
Номер сметка на наредителя / получателя: No sort applied, activate to apply an ascending sort
▲
НОМЕР СМЕТКА НА НАРЕДИТЕЛЯ / ПОЛУЧАТЕЛЯ
▼
Дебит: No sort applied, activate to apply an ascending sort
▲
ДЕБИТ
▼
Кредит: No sort applied, activate to apply an ascending sort
▲
КРЕДИТ
▼
04.05.2026
04.05.2026 ПРОФЕСИОНАЛЕН ДОМОУАБ.N. 14044121 НАШИЯТ ВХОД ООД
КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ
[IBAN]
17.93
04.05.2026
04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
[IBAN]
8.44
04.05.2026
04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
[IBAN]
47.63
04.05.2026
04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
[IBAN]
0.09
04.05.2026
04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
[IBAN]
29.54
04.05.2026
04.05.2026 ПРИРОДЕН ГАЗ АБ.N. 1000083763 OVERGAS
ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА
[IBAN]
14.27
04.05.2026
ДАНИЕЛ КОВАЛИК МАЙ
ЧЦДГ МИЛА
[IBAN]
460.00
30.04.2026
ТАКСА ПАКЕТНО ОБСЛУЖВАНЕ
[CREDIT_CARD]
10.22
30.04.2026
ЗАПЛАТА ЗА МЕСЕЦ 04.2026 OPNAT 0
ВЕДА ПЕЙРОЛ ООД
[IBAN]
4 325.26
22.04.2026
ЗАХРАНВАНЕ СМЕТКА ISI2204260011502
МАРТИНА СВЕТОСЛАВОВА КОВАЛИК
[IBAN]
1 000.00
Общо
588.12
5 325.26
: No sort applied, sorting is disabled
Общо
Дата: No sort applied, activate to apply an ascending sort
▲
ДАТА
▼
04.05.2026
04.05.2026
04.05.2026
04.05.2026
04.05.2026
04.05.2026
04.05.2026
30.04.2026
30.04.2026
22.04.2026
Общо
Основание: No sort applied, activate to apply an ascending sort
▲
ОСНОВАНИЕ
▼
04.05.2026 ПРОФЕСИОНАЛЕН ДОМОУАБ.N. 14044121 НАШИЯТ ВХОД ООД
04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД
04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД
04.05.2026 ЕЛ ЕНЕРГИЯ АБ.N. 310264962737 ЕЛЕКТРОХОЛД ПРОДАЖБИ АД
04.05.2026 СТУДЕНА ВОДА АБ.N. 1005400804 СОФИЙСКА ВОДА АД
04.05.2026 ПРИРОДЕН ГАЗ АБ.N. 1000083763 OVERGAS
ДАНИЕЛ КОВАЛИК МАЙ
ТАКСА ПАКЕТНО ОБСЛУЖВАНЕ
ЗАПЛАТА ЗА МЕСЕЦ 04.2026 OPNAT 0
ЗАХРАНВАНЕ СМЕТКА ISI2204260011502
Общо
Наредител/Получател: No sort applied, activate to apply an ascending sort
▲
НАРЕДИТЕЛ/ПОЛУЧАТЕЛ
▼
КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА
ЧЦДГ МИЛА
ВЕДА ПЕЙРОЛ ООД
МАРТИНА СВЕТОСЛАВОВА КОВАЛИК
Общо
Номер сметка на наредителя / получателя: No sort applied, activate to apply an ascending sort
▲
НОМЕР СМЕТКА НА НАРЕДИТЕЛЯ / ПОЛУЧАТЕЛЯ
▼
[IBAN]
[IBAN]
[IBAN]
[IBAN]
[IBAN]
[IBAN]
[IBAN]
[CREDIT_CARD]
[IBAN]
[IBAN]
Общо
Дебит: No sort applied, activate to apply an ascending sort
▲
ДЕБИТ
▼
17.93
8.44
47.63
0.09
29.54
14.27
460.00
10.22
588.12
Кредит: No sort applied, activate to apply an ascending sort
▲
КРЕДИТ
▼
4 325.26
1 000.00
5 325.26
*Фиксиран курс за целите на двойно обозначение 1 EUR = 1.95583 BGN
Потребителско ръководство - граждани
Потребителско ръководство - граждани
Общи условия за граждани
Общи условия за граждани
Тарифа за граждани
Тарифа за граждани
Call center:
*2375
0700 10 375
Потребителско ръководство - фирми
Потребителско ръководство - фирми
Общи условия за фирми
Общи условия за фирми
Тарифа за фирми
Тарифа за фирми
BIC/SWIFT на Банка ДСК: STSABGSF ©
2026 on DAIS eBank .NET...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
21468
|
940
|
3
|
2026-05-11T17:57:54.003777+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778522274003_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
_meta
table in the source DB) to every synced table, and make
(install_id, id)
the logical key. FK joins just gain one extra predicate. Reinstall → new install_id → no collisions, ever. You can still rotate the archive DB quarterly for file-size reasons, but it's no longer load-bearing.
Do you ever run cross-period queries (e.g. "every frame mentioning JY-20458 across all time")? That answers whether quarterly sharding is acceptable or whether one growing DB is better.
Issue 2 — Mac-side retention
Your launch command already has
--retention-days 7
. Is that not actually deleting anything, or do you want a separate scripted retention you can trust/observe independently?
Should retention also wipe the matching
~/.screenpipe/data/data/YYYY-MM-DD/
folders, or only DB rows? (CLI flag does both I believe; a script should match.)
Run order matters: sync writes
yesterday
, retention deletes
>7 days old
— no overlap, but I'd still chain them (sync → retention → log) in one cron entry so a failed sync blocks the delete. OK with that?
Issue 3 — Audio
Your current launch flag is
--disable-audio
, so right now there's no audio data to sync. Are you planning to enable it, or is this just to future-proof the script?
I need the audio schema. Could you run this and paste the output:
Copy to clipboard
sqlite3 ~/.screenpipe/db.sqlite ".schema" | grep -iE -A 20 "audio|transcription"
And:
ls ~/.screenpipe/data/data/$(date -v-1d +%Y-%m-%d)/ | head
so I can see what audio files look like on disk alongside the mp4 frames.
Once I have those, I'll restructure the script in one go rather than piecemeal.
Copy
Give positive feedback
Give negative feedback
Retry
You said: ok lets add install_id.
You said: ok lets add install_id.
Pasted Text, pasted, 208 lines
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ sqlite3 ~/.screenpipe/db.sqlite ".schema" | grep -iE -A 20 "audio|transcription" CREATE TABLE audio_chunks ( id INTEGER PRIMARY KEY AUTOINCREMENT, file_path TEXT NOT NULL , timestamp TIMESTAMP, sync_id TEXT, machine_id TEXT, synced_at DATETIME, ev
PASTED
ok lets add install_id. Lets add separate script deleting data again from data and it should also remove logs and data. Make it manual script for now. I will remove --disable-audio from alias and run it without. I wan to have audio as well. lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ ls ~/.screenpipe/data/data/$(date -v-1d +%Y-%m-%d)/ | head
compact_monitor_1_1778411210025.mp4
compact_monitor_1_1778413422547.mp4
compact_monitor_1_1778436664801.mp4
compact_monitor_1_1778437267451.mp4
compact_monitor_1_1778437569681.mp4
compact_monitor_1_1778437873507.mp4
compact_monitor_1_1778438175846.mp4
compact_monitor_1_1778438477299.mp4
compact_monitor_1_1778438780686.mp4
compact_monitor_1_1778439082442.mp4 Inside ~/,screenpipe/data there are data like this ... -rw-r--r-- 1 lukas staff 4628 11 May 16:48 System Audio (output)_2026-05-11_13-48-12.mp4
-rw-r--r-- 1 lukas staff 4620 11 May 16:48 System Audio (output)_2026-05-11_13-48-34.mp4
-rw-r--r-- 1 lukas staff 4620 11 May 16:49 System Audio (output)_2026-05-11_13-48-56.mp4
-rw-r--r-- 1 lukas staff 4628 11 May 16:49 System Audio (output)_2026-05-11_13-49-19.mp4
-rw-r--r-- 1 lukas staff 4620 11 May 16:50 System Audio (output)_2026-05-11_13-49-41.mp4
-rw-r--r-- 1 lukas staff 4620 11 May 16:50 System Audio (output)_2026-05-11_13-50-03.mp4
-rw-r--r-- 1 lukas staff 4628 11 May 16:50 System Audio (output)_2026-05-11_13-50-26.mp4
-rw-r--r-- 1 lukas staff 4628 11 May 16:51 System Audio (output)_2026-05-11_13-50-48.mp4
-rw-r--r-- 1 lukas staff 4620 11 May 16:51 System Audio (output)_2026-05-11_13-51-10.mp4
-rw-r--r-- 1 lukas staff 4620 11 May 16:51 System Audio (output)_2026-05-11_13-51-33.mp4
-rw-r--r-- 1 lukas staff 4620 11 May 16:52 System Audio (output)_2026-05-11_13-51-55.mp4
drwxr-xr-x 9 lukas staff 288 11 May 07:54 data
drwxr-xr-x 2 lukas staff 64 11 May 15:48 pending-transcriptions
-rw-r--r-- 1 lukas staff 29419 10 May 14:11 soundcore AeroClip (input)_2026-05-10_11-10-32.mp4
-rw-r--r-- 1 lukas staff 56479 10 May 14:11 soundcore AeroClip (input)_2026-05-10_11-11-05.mp4
-rw-r--r--@ 1 lukas staff 181831 10 May 14:12 soundcore AeroClip (input)_2026-05-10_11-11-35.mp4
-rw-r--r-- 1 lukas staff 149782 10 May 14:43 soundcore AeroClip (input)_2026-05-10_11-42-53.mp4
-rw-r--r-- 1 lukas staff 91059 10 May 14:43 soundcore AeroClip (input)_2026-05-10_11-43-25.mp4
-rw-r--r-- 1 lukas staff 30604 10 May 14:44 soundcore AeroClip (input)_2026-05-10_11-44-25.mp4
-rw-r--r-- 1 lukas staff 93813 10 May 14:45 soundcore AeroClip (input)_2026-05-10_11-44-55.mp4
-rw-r--r-- 1 lukas staff 40444 10 May 21:11 soundcore AeroClip (input)_2026-05-10_18-11-18.mp4
-rw-r--r-- 1 lukas staff 193020 10 May 21:12 soundcore AeroClip (input)_2026-05-10_18-11-48.mp4...
Show more
20:34
Retry
Edit
Copy
Claude responded: Good, that clarifies the audio layout — audio files live flat in ~/.
Claude responded: Good, that clarifies the audio layout — audio files live flat in ~/.
Architected multi-install sync with audio support and retention
Architected multi-install sync with audio support and retention
Good, that clarifies the audio layout — audio files live flat in
~/.screenpipe/data/
with the date in the filename (not in date subdirs like frames), and the schema gives us
audio_chunks
+
audio_transcriptions
+
speakers
+
speaker_embeddings
+
audio_tags
plus the FTS table on transcriptions.
Plan I'll implement:
install_id
: stored as a UUID in
~/.screenpipe/.sync_install_id
— disappears when the directory is wiped (which is what you want on reinstall). Every synced NAS table gets an
install_id TEXT
column and a
UNIQUE(install_id, id)
index. The script auto-migrates the existing NAS archive by adding the column and tagging legacy rows with
legacy-YYYYMMDD
so historical data is still queryable but doesn't conflict with future installs.
Audio sync
: adds
audio_chunks
,
audio_transcriptions
,
speakers
,
speaker_embeddings
,
audio_tags
to the sync pipeline, plus the
audio_transcriptions_fts
index. Audio files go to
$NAS_DATA/<date>/audio/
(sibling to the frames in the same date dir, keeps daily archives self-contained).
Retention
is a separate manual script — dry-run by default,
--apply
to delete. Hits DB rows, frame directories, audio mp4s, and screenpipe logs. Optional
--vacuum
with a warning (screenpipe must be stopped to avoid blocking writes for minutes).
One caveat I'm punting on: the FTS tables use source
id
as
rowid
, so after a reinstall they'd get id-collisions on insert and
INSERT OR IGNORE
would silently skip. Within a single install this is fine; after reinstall you'd fall back to
LIKE
queries on the base tables (still filterable by
install_id
). I noted this in the script. Fixing it properly needs a synthetic rowid scheme which we can do later if you actually hit it.
Let me write both:
Updated screenpipe_sync.sh with install_id support and audio sync
Updated screenpipe_sync.sh with install_id support and audio sync
Updated screenpipe_sync.sh with install_id support and audio sync
Updated screenpipe_sync.sh with install_id support and audio sync
screenpipe_sync.sh
Done
Copy
Give positive feedback
Give negative feedback
Retry
You said: I don't like that.
You said: I don't like that.
I don't like that. It should be solid without id collisions. Wouldn't it be to late if I should fix it later?
20:50
Retry
Edit
Copy
You're out of extra usage
∙
Your limit resets at 12:10 AM
Buy more
I don't like that. It should be solid without id collisions. Wouldn't it be to late if I should fix it later?
I don't like that. It should be solid without id collisions. Wouldn't it be to late if I should fix it later?
Add files, connectors, and more
Model: Opus 4.7 Adaptive
Opus 4.7
Adaptive
Send message
Claude is AI and can make mistakes. Please double-check responses.
Claude is AI and can make mistakes. Please double-check responses.
Screenpipe sync · SH
Screenpipe sync
·
SH
Copy
Close
1
#!/bin/bash
2
# screenpipe_sync.sh
3
# Syncs Screenpipe SQLite data (vision + audio) to a NAS archive database.
4
# Append-only, no deletions.
5
#
6
# Key design points
7
# -----------------
8
# 1. Multi-install safe via install_id.
9
# Source IDs reset to 1 on every screenpipe reinstall. To avoid collisions
10
# in the NAS archive, every synced table gets an extra `install_id` column,
11
# and the logical primary key becomes (install_id, id) enforced by a
12
# unique index. The install_id is a UUID stored in
13
# ~/.screenpipe/.sync_install_id — wiping ~/.screenpipe/ (which is what
14
# happens on reinstall) discards it, so the next run generates a new one.
15
#
16
# 2. Schema-drift tolerant. If screenpipe migrations add new columns to the
17
# source DB, the NAS gets ALTER TABLE'd to match. Inserts use explicit
18
# column lists so positional mismatches can't occur.
19
#
20
# 3. FTS caveat. FTS tables in the NAS use source `id` as rowid. After a
21
# reinstall, INSERT OR IGNORE will silently skip rows whose id collides
22
# with a previous install's id, so FTS only reliably indexes the most
23
# recent install. Falls back to LIKE queries on the base tables for
24
# multi-install searches (which can filter by install_id).
25
#
26
# Usage
27
# -----
28
# ./screenpipe_sync.sh # syncs yesterday
29
# ./screenpipe_sync.sh 2026-04-15 # syncs a specific date
30
# ./screenpipe_sync.sh today # syncs today so far
31
# ./screenpipe_sync.sh --reset-install-id # rotate install_id and exit
32
# ./screenpipe_sync.sh --show-install-id # print install_id and exit
33
34
set
-euo
pipefail
35
36
# ─── CONFIG ───────────────────────────────────────────────────────────────────
37
DB_SRC
=
"${SCREENPIPE_DB:-$HOME/.screenpipe/db.sqlite}"
38
NAS_MOUNT
=
"${NAS_MOUNT:-/Volumes/screenpipe}"
39
NAS_DB
=
"$NAS_MOUNT/archive.db"
40
NAS_DATA
=
"$NAS_MOUNT/data"
41
LOG_FILE
=
"$HOME/.screenpipe/sync.log"
42
INSTALL_ID_FILE
=
"$HOME/.screenpipe/.sync_install_id"
43
44
# Sync table groups. Order matters for FK-ish references
45
# (parents before children).
46
VISION_TABLES
=(video_chunks frames elements ocr_text ui_events meetings)
47
AUDIO_TABLES
=(speakers speaker_embeddings audio_chunks audio_transcriptions audio_tags)
48
ALL_SYNC_TABLES
=(
"${VISION_TABLES[@]}"
"${AUDIO_TABLES[@]}"
)
49
# ──────────────────────────────────────────────────────────────────────────────
50
51
SCRIPT_START
=
$(date +%s)
52
53
# ─── HELPERS ──────────────────────────────────────────────────────────────────
54
log
() {
55
local
msg
=
"[$(date '+%Y-%m-%d %H:%M:%S')] $*"
56
echo
"$msg"
|
tee
-a
"$LOG_FILE"
57
}
58
59
step
() {
60
local
now
=
$(date +%s)
61
local
elapsed
=$((
now
-
SCRIPT_START
))
62
local
min
=$((
elapsed
/ 60 ))
63
local
sec
=$((
elapsed
% 60 ))
64
printf
"\n[+%02dm%02ds] ▶ %s\n"
"$min"
"$sec"
"$*"
|
tee
-a
"$LOG_FILE"
65
}
66
67
run_sqlite_heredoc
() {
68
local
label
=
"$1"
69
local
sql
=
"$2"
70
local
start
=
$(date +%s)
71
72
printf
" %-36s "
"$label"
73
74
sqlite3
"$DB_SRC"
<<<
"$sql"
&
75
local
pid
=
$
!
76...
|
[{"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,"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,"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"},{"role":"AXStaticText","text":"_meta","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"table in the source DB) to every synced table, and make","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(install_id, id)","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"the logical key. FK joins just gain one extra predicate. Reinstall → new install_id → no collisions, ever. You can still rotate the archive DB quarterly for file-size reasons, but it's no longer load-bearing.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Do you ever run cross-period queries (e.g. \"every frame mentioning JY-20458 across all time\")? That answers whether quarterly sharding is acceptable or whether one growing DB is better.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Issue 2 — Mac-side retention","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Your launch command already has","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"--retention-days 7","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":". Is that not actually deleting anything, or do you want a separate scripted retention you can trust/observe independently?","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Should retention also wipe the matching","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"~/.screenpipe/data/data/YYYY-MM-DD/","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"folders, or only DB rows? (CLI flag does both I believe; a script should match.)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Run order matters: sync writes","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"yesterday","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", retention deletes","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":">7 days old","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— no overlap, but I'd still chain them (sync → retention → log) in one cron entry so a failed sync blocks the delete. OK with that?","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Issue 3 — Audio","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Your current launch flag is","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"--disable-audio","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", so right now there's no audio data to sync. Are you planning to enable it, or is this just to future-proof the script?","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"I need the audio schema. Could you run this and paste the output:","depth":26,"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":"sqlite3 ~/.screenpipe/db.sqlite \".schema\" | grep -iE -A 20 \"audio|transcription\"","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"And:","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ls ~/.screenpipe/data/data/$(date -v-1d +%Y-%m-%d)/ | head","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"so I can see what audio files look like on disk alongside the mp4 frames.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Once I have those, I'll restructure the script in one go rather than piecemeal.","depth":25,"on_screen":false,"role_description":"text"},{"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":"AXButton","text":"Give positive feedback","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Give negative feedback","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"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":"AXHeading","text":"You said: ok lets add install_id.","depth":20,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"You said: ok lets add install_id.","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Pasted Text, pasted, 208 lines","depth":21,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ sqlite3 ~/.screenpipe/db.sqlite \".schema\" | grep -iE -A 20 \"audio|transcription\" CREATE TABLE audio_chunks ( id INTEGER PRIMARY KEY AUTOINCREMENT, file_path TEXT NOT NULL , timestamp TIMESTAMP, sync_id TEXT, machine_id TEXT, synced_at DATETIME, ev","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PASTED","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ok lets add install_id. Lets add separate script deleting data again from data and it should also remove logs and data. Make it manual script for now. I will remove --disable-audio from alias and run it without. I wan to have audio as well. lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ ls ~/.screenpipe/data/data/$(date -v-1d +%Y-%m-%d)/ | head\ncompact_monitor_1_1778411210025.mp4\ncompact_monitor_1_1778413422547.mp4\ncompact_monitor_1_1778436664801.mp4\ncompact_monitor_1_1778437267451.mp4\ncompact_monitor_1_1778437569681.mp4\ncompact_monitor_1_1778437873507.mp4\ncompact_monitor_1_1778438175846.mp4\ncompact_monitor_1_1778438477299.mp4\ncompact_monitor_1_1778438780686.mp4\ncompact_monitor_1_1778439082442.mp4 Inside ~/,screenpipe/data there are data like this ... -rw-r--r-- 1 lukas staff 4628 11 May 16:48 System Audio (output)_2026-05-11_13-48-12.mp4\n-rw-r--r-- 1 lukas staff 4620 11 May 16:48 System Audio (output)_2026-05-11_13-48-34.mp4\n-rw-r--r-- 1 lukas staff 4620 11 May 16:49 System Audio (output)_2026-05-11_13-48-56.mp4\n-rw-r--r-- 1 lukas staff 4628 11 May 16:49 System Audio (output)_2026-05-11_13-49-19.mp4\n-rw-r--r-- 1 lukas staff 4620 11 May 16:50 System Audio (output)_2026-05-11_13-49-41.mp4\n-rw-r--r-- 1 lukas staff 4620 11 May 16:50 System Audio (output)_2026-05-11_13-50-03.mp4\n-rw-r--r-- 1 lukas staff 4628 11 May 16:50 System Audio (output)_2026-05-11_13-50-26.mp4\n-rw-r--r-- 1 lukas staff 4628 11 May 16:51 System Audio (output)_2026-05-11_13-50-48.mp4\n-rw-r--r-- 1 lukas staff 4620 11 May 16:51 System Audio (output)_2026-05-11_13-51-10.mp4\n-rw-r--r-- 1 lukas staff 4620 11 May 16:51 System Audio (output)_2026-05-11_13-51-33.mp4\n-rw-r--r-- 1 lukas staff 4620 11 May 16:52 System Audio (output)_2026-05-11_13-51-55.mp4\ndrwxr-xr-x 9 lukas staff 288 11 May 07:54 data\ndrwxr-xr-x 2 lukas staff 64 11 May 15:48 pending-transcriptions\n-rw-r--r-- 1 lukas staff 29419 10 May 14:11 soundcore AeroClip (input)_2026-05-10_11-10-32.mp4\n-rw-r--r-- 1 lukas staff 56479 10 May 14:11 soundcore AeroClip (input)_2026-05-10_11-11-05.mp4\n-rw-r--r--@ 1 lukas staff 181831 10 May 14:12 soundcore AeroClip (input)_2026-05-10_11-11-35.mp4\n-rw-r--r-- 1 lukas staff 149782 10 May 14:43 soundcore AeroClip (input)_2026-05-10_11-42-53.mp4\n-rw-r--r-- 1 lukas staff 91059 10 May 14:43 soundcore AeroClip (input)_2026-05-10_11-43-25.mp4\n-rw-r--r-- 1 lukas staff 30604 10 May 14:44 soundcore AeroClip (input)_2026-05-10_11-44-25.mp4\n-rw-r--r-- 1 lukas staff 93813 10 May 14:45 soundcore AeroClip (input)_2026-05-10_11-44-55.mp4\n-rw-r--r-- 1 lukas staff 40444 10 May 21:11 soundcore AeroClip (input)_2026-05-10_18-11-18.mp4\n-rw-r--r-- 1 lukas staff 193020 10 May 21:12 soundcore AeroClip (input)_2026-05-10_18-11-48.mp4...","depth":24,"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":"20:34","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, that clarifies the audio layout — audio files live flat in ~/.","depth":21,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Claude responded: Good, that clarifies the audio layout — audio files live flat in ~/.","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Architected multi-install sync with audio support and retention","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Architected multi-install sync with audio support and retention","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Good, that clarifies the audio layout — audio files live flat in","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"~/.screenpipe/data/","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"with the date in the filename (not in date subdirs like frames), and the schema gives us","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"audio_chunks","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"+","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"audio_transcriptions","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"+","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"speakers","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"+","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"speaker_embeddings","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"+","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"audio_tags","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"plus the FTS table on transcriptions.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Plan I'll implement:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"install_id","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":": stored as a UUID in","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"~/.screenpipe/.sync_install_id","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— disappears when the directory is wiped (which is what you want on reinstall). Every synced NAS table gets an","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"install_id TEXT","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"column and a","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UNIQUE(install_id, id)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"index. The script auto-migrates the existing NAS archive by adding the column and tagging legacy rows with","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"legacy-YYYYMMDD","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"so historical data is still queryable but doesn't conflict with future installs.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Audio sync","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":": adds","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"audio_chunks","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"audio_transcriptions","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"speakers","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"speaker_embeddings","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"audio_tags","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"to the sync pipeline, plus the","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"audio_transcriptions_fts","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"index. Audio files go to","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"$NAS_DATA/<date>/audio/","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(sibling to the frames in the same date dir, keeps daily archives self-contained).","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Retention","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"is a separate manual script — dry-run by default,","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"--apply","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"to delete. Hits DB rows, frame directories, audio mp4s, and screenpipe logs. Optional","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"--vacuum","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"with a warning (screenpipe must be stopped to avoid blocking writes for minutes).","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"One caveat I'm punting on: the FTS tables use source","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"id","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"as","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"rowid","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", so after a reinstall they'd get id-collisions on insert and","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"INSERT OR IGNORE","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"would silently skip. Within a single install this is fine; after reinstall you'd fall back to","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"LIKE","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"queries on the base tables (still filterable by","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"install_id","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"). I noted this in the script. Fixing it properly needs a synthetic rowid scheme which we can do later if you actually hit it.","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Let me write both:","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Updated screenpipe_sync.sh with install_id support and audio sync","depth":22,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Updated screenpipe_sync.sh with install_id support and audio sync","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Updated screenpipe_sync.sh with install_id support and audio sync","depth":23,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Updated screenpipe_sync.sh with install_id support and audio sync","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"screenpipe_sync.sh","depth":24,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Done","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Copy","depth":22,"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,"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,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Retry","depth":22,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"You said: I don't like that.","depth":20,"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"You said: I don't like that.","depth":21,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"I don't like that. It should be solid without id collisions. Wouldn't it be to late if I should fix it later?","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"20:50","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Retry","depth":22,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Edit","depth":22,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Copy","depth":22,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"You're out of extra usage","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"∙","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Your limit resets at 12:10 AM","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Buy more","depth":25,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"I don't like that. It should be solid without id collisions. Wouldn't it be to late if I should fix it later?","depth":25,"on_screen":true,"value":"I don't like that. It should be solid without id collisions. Wouldn't it be to late if I should fix it later?","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"I don't like that. It should be solid without id collisions. Wouldn't it be to late if I should fix it later?","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Add files, connectors, and more","depth":27,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Model: Opus 4.7 Adaptive","depth":27,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Opus 4.7","depth":29,"bounds":{"left":0.0,"top":0.0,"width":0.04027778,"height":0.018888889},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Adaptive","depth":28,"bounds":{"left":0.0,"top":0.0,"width":0.041666668,"height":0.018888889},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Send message","depth":26,"bounds":{"left":0.010416667,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Claude is AI and can make mistakes. Please double-check responses.","depth":22,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Claude is AI and can make mistakes. Please double-check responses.","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXHeading","text":"Screenpipe sync · SH","depth":19,"on_screen":true,"help_text":"Screenpipe sync","role_description":"heading"},{"role":"AXStaticText","text":"Screenpipe sync","depth":20,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"·","depth":20,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SH","depth":20,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Copy","depth":19,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":19,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"#!/bin/bash","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# screenpipe_sync.sh","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"3","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# Syncs Screenpipe SQLite data (vision + audio) to a NAS archive database.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# Append-only, no deletions.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"5","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"#","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"6","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# Key design points","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"7","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# -----------------","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"8","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# 1. Multi-install safe via install_id.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"9","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# Source IDs reset to 1 on every screenpipe reinstall. To avoid collisions","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"10","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# in the NAS archive, every synced table gets an extra `install_id` column,","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"11","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# and the logical primary key becomes (install_id, id) enforced by a","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"12","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# unique index. The install_id is a UUID stored in","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"13","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# ~/.screenpipe/.sync_install_id — wiping ~/.screenpipe/ (which is what","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"14","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# happens on reinstall) discards it, so the next run generates a new one.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"15","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"#","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"16","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# 2. Schema-drift tolerant. If screenpipe migrations add new columns to the","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"17","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# source DB, the NAS gets ALTER TABLE'd to match. Inserts use explicit","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"18","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# column lists so positional mismatches can't occur.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"19","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"#","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"20","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# 3. FTS caveat. FTS tables in the NAS use source `id` as rowid. After a","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"21","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# reinstall, INSERT OR IGNORE will silently skip rows whose id collides","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"22","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# with a previous install's id, so FTS only reliably indexes the most","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"23","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# recent install. Falls back to LIKE queries on the base tables for","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"24","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# multi-install searches (which can filter by install_id).","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"25","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"#","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"26","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# Usage","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"27","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# -----","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"28","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# ./screenpipe_sync.sh # syncs yesterday","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"29","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# ./screenpipe_sync.sh 2026-04-15 # syncs a specific date","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"30","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# ./screenpipe_sync.sh today # syncs today so far","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"31","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# ./screenpipe_sync.sh --reset-install-id # rotate install_id and exit","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"32","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# ./screenpipe_sync.sh --show-install-id # print install_id and exit","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"33","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"34","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"set","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-euo","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"pipefail","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"35","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"36","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# ─── CONFIG ───────────────────────────────────────────────────────────────────","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"37","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DB_SRC","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"${SCREENPIPE_DB:-$HOME/.screenpipe/db.sqlite}\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"38","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"NAS_MOUNT","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"${NAS_MOUNT:-/Volumes/screenpipe}\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"39","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"NAS_DB","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"$NAS_MOUNT/archive.db\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"NAS_DATA","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"$NAS_MOUNT/data\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"41","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LOG_FILE","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"$HOME/.screenpipe/sync.log\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"42","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"INSTALL_ID_FILE","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"$HOME/.screenpipe/.sync_install_id\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"43","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"44","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# Sync table groups. Order matters for FK-ish references","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"45","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# (parents before children).","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"46","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"VISION_TABLES","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=(video_chunks frames elements ocr_text ui_events meetings)","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"47","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AUDIO_TABLES","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=(speakers speaker_embeddings audio_chunks audio_transcriptions audio_tags)","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"48","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ALL_SYNC_TABLES","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=(","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"${VISION_TABLES[@]}\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"${AUDIO_TABLES[@]}\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":")","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"49","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# ──────────────────────────────────────────────────────────────────────────────","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"50","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"51","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SCRIPT_START","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"$(date +%s)","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"52","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"53","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# ─── HELPERS ──────────────────────────────────────────────────────────────────","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"54","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"log","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"() {","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"55","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"local","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"msg","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"[$(date '+%Y-%m-%d %H:%M:%S')] $*\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"56","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"echo","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"$msg\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"|","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"tee","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-a","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"$LOG_FILE\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"57","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"}","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"58","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"59","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"step","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"() {","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"60","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"local","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"now","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"$(date +%s)","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"61","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"local","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"elapsed","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=$((","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"now","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SCRIPT_START","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"))","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"62","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"local","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"min","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=$((","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"elapsed","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/ 60 ))","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"63","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"local","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"sec","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=$((","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"elapsed","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"% 60 ))","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"printf","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"\\n[+%02dm%02ds] ▶ %s\\n\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"$min\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"$sec\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"$*\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"|","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"tee","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-a","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"$LOG_FILE\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"65","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"}","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"66","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"67","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"run_sqlite_heredoc","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"() {","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"68","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"local","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"label","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"$1\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"69","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"local","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"sql","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"$2\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"70","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"local","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"start","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"$(date +%s)","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"71","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"72","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"printf","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\" %-36s \"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"$label\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"73","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"74","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"sqlite3","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"$DB_SRC\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"<<<","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\"$sql\"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"&","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"75","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"local","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"pid","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"$","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"!","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"76","depth":22,"on_screen":false,"role_description":"text"}]...
|
-8252729820272324296
|
-8490785551363998525
|
visual_change
|
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
_meta
table in the source DB) to every synced table, and make
(install_id, id)
the logical key. FK joins just gain one extra predicate. Reinstall → new install_id → no collisions, ever. You can still rotate the archive DB quarterly for file-size reasons, but it's no longer load-bearing.
Do you ever run cross-period queries (e.g. "every frame mentioning JY-20458 across all time")? That answers whether quarterly sharding is acceptable or whether one growing DB is better.
Issue 2 — Mac-side retention
Your launch command already has
--retention-days 7
. Is that not actually deleting anything, or do you want a separate scripted retention you can trust/observe independently?
Should retention also wipe the matching
~/.screenpipe/data/data/YYYY-MM-DD/
folders, or only DB rows? (CLI flag does both I believe; a script should match.)
Run order matters: sync writes
yesterday
, retention deletes
>7 days old
— no overlap, but I'd still chain them (sync → retention → log) in one cron entry so a failed sync blocks the delete. OK with that?
Issue 3 — Audio
Your current launch flag is
--disable-audio
, so right now there's no audio data to sync. Are you planning to enable it, or is this just to future-proof the script?
I need the audio schema. Could you run this and paste the output:
Copy to clipboard
sqlite3 ~/.screenpipe/db.sqlite ".schema" | grep -iE -A 20 "audio|transcription"
And:
ls ~/.screenpipe/data/data/$(date -v-1d +%Y-%m-%d)/ | head
so I can see what audio files look like on disk alongside the mp4 frames.
Once I have those, I'll restructure the script in one go rather than piecemeal.
Copy
Give positive feedback
Give negative feedback
Retry
You said: ok lets add install_id.
You said: ok lets add install_id.
Pasted Text, pasted, 208 lines
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ sqlite3 ~/.screenpipe/db.sqlite ".schema" | grep -iE -A 20 "audio|transcription" CREATE TABLE audio_chunks ( id INTEGER PRIMARY KEY AUTOINCREMENT, file_path TEXT NOT NULL , timestamp TIMESTAMP, sync_id TEXT, machine_id TEXT, synced_at DATETIME, ev
PASTED
ok lets add install_id. Lets add separate script deleting data again from data and it should also remove logs and data. Make it manual script for now. I will remove --disable-audio from alias and run it without. I wan to have audio as well. lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ ls ~/.screenpipe/data/data/$(date -v-1d +%Y-%m-%d)/ | head
compact_monitor_1_1778411210025.mp4
compact_monitor_1_1778413422547.mp4
compact_monitor_1_1778436664801.mp4
compact_monitor_1_1778437267451.mp4
compact_monitor_1_1778437569681.mp4
compact_monitor_1_1778437873507.mp4
compact_monitor_1_1778438175846.mp4
compact_monitor_1_1778438477299.mp4
compact_monitor_1_1778438780686.mp4
compact_monitor_1_1778439082442.mp4 Inside ~/,screenpipe/data there are data like this ... -rw-r--r-- 1 lukas staff 4628 11 May 16:48 System Audio (output)_2026-05-11_13-48-12.mp4
-rw-r--r-- 1 lukas staff 4620 11 May 16:48 System Audio (output)_2026-05-11_13-48-34.mp4
-rw-r--r-- 1 lukas staff 4620 11 May 16:49 System Audio (output)_2026-05-11_13-48-56.mp4
-rw-r--r-- 1 lukas staff 4628 11 May 16:49 System Audio (output)_2026-05-11_13-49-19.mp4
-rw-r--r-- 1 lukas staff 4620 11 May 16:50 System Audio (output)_2026-05-11_13-49-41.mp4
-rw-r--r-- 1 lukas staff 4620 11 May 16:50 System Audio (output)_2026-05-11_13-50-03.mp4
-rw-r--r-- 1 lukas staff 4628 11 May 16:50 System Audio (output)_2026-05-11_13-50-26.mp4
-rw-r--r-- 1 lukas staff 4628 11 May 16:51 System Audio (output)_2026-05-11_13-50-48.mp4
-rw-r--r-- 1 lukas staff 4620 11 May 16:51 System Audio (output)_2026-05-11_13-51-10.mp4
-rw-r--r-- 1 lukas staff 4620 11 May 16:51 System Audio (output)_2026-05-11_13-51-33.mp4
-rw-r--r-- 1 lukas staff 4620 11 May 16:52 System Audio (output)_2026-05-11_13-51-55.mp4
drwxr-xr-x 9 lukas staff 288 11 May 07:54 data
drwxr-xr-x 2 lukas staff 64 11 May 15:48 pending-transcriptions
-rw-r--r-- 1 lukas staff 29419 10 May 14:11 soundcore AeroClip (input)_2026-05-10_11-10-32.mp4
-rw-r--r-- 1 lukas staff 56479 10 May 14:11 soundcore AeroClip (input)_2026-05-10_11-11-05.mp4
-rw-r--r--@ 1 lukas staff 181831 10 May 14:12 soundcore AeroClip (input)_2026-05-10_11-11-35.mp4
-rw-r--r-- 1 lukas staff 149782 10 May 14:43 soundcore AeroClip (input)_2026-05-10_11-42-53.mp4
-rw-r--r-- 1 lukas staff 91059 10 May 14:43 soundcore AeroClip (input)_2026-05-10_11-43-25.mp4
-rw-r--r-- 1 lukas staff 30604 10 May 14:44 soundcore AeroClip (input)_2026-05-10_11-44-25.mp4
-rw-r--r-- 1 lukas staff 93813 10 May 14:45 soundcore AeroClip (input)_2026-05-10_11-44-55.mp4
-rw-r--r-- 1 lukas staff 40444 10 May 21:11 soundcore AeroClip (input)_2026-05-10_18-11-18.mp4
-rw-r--r-- 1 lukas staff 193020 10 May 21:12 soundcore AeroClip (input)_2026-05-10_18-11-48.mp4...
Show more
20:34
Retry
Edit
Copy
Claude responded: Good, that clarifies the audio layout — audio files live flat in ~/.
Claude responded: Good, that clarifies the audio layout — audio files live flat in ~/.
Architected multi-install sync with audio support and retention
Architected multi-install sync with audio support and retention
Good, that clarifies the audio layout — audio files live flat in
~/.screenpipe/data/
with the date in the filename (not in date subdirs like frames), and the schema gives us
audio_chunks
+
audio_transcriptions
+
speakers
+
speaker_embeddings
+
audio_tags
plus the FTS table on transcriptions.
Plan I'll implement:
install_id
: stored as a UUID in
~/.screenpipe/.sync_install_id
— disappears when the directory is wiped (which is what you want on reinstall). Every synced NAS table gets an
install_id TEXT
column and a
UNIQUE(install_id, id)
index. The script auto-migrates the existing NAS archive by adding the column and tagging legacy rows with
legacy-YYYYMMDD
so historical data is still queryable but doesn't conflict with future installs.
Audio sync
: adds
audio_chunks
,
audio_transcriptions
,
speakers
,
speaker_embeddings
,
audio_tags
to the sync pipeline, plus the
audio_transcriptions_fts
index. Audio files go to
$NAS_DATA/<date>/audio/
(sibling to the frames in the same date dir, keeps daily archives self-contained).
Retention
is a separate manual script — dry-run by default,
--apply
to delete. Hits DB rows, frame directories, audio mp4s, and screenpipe logs. Optional
--vacuum
with a warning (screenpipe must be stopped to avoid blocking writes for minutes).
One caveat I'm punting on: the FTS tables use source
id
as
rowid
, so after a reinstall they'd get id-collisions on insert and
INSERT OR IGNORE
would silently skip. Within a single install this is fine; after reinstall you'd fall back to
LIKE
queries on the base tables (still filterable by
install_id
). I noted this in the script. Fixing it properly needs a synthetic rowid scheme which we can do later if you actually hit it.
Let me write both:
Updated screenpipe_sync.sh with install_id support and audio sync
Updated screenpipe_sync.sh with install_id support and audio sync
Updated screenpipe_sync.sh with install_id support and audio sync
Updated screenpipe_sync.sh with install_id support and audio sync
screenpipe_sync.sh
Done
Copy
Give positive feedback
Give negative feedback
Retry
You said: I don't like that.
You said: I don't like that.
I don't like that. It should be solid without id collisions. Wouldn't it be to late if I should fix it later?
20:50
Retry
Edit
Copy
You're out of extra usage
∙
Your limit resets at 12:10 AM
Buy more
I don't like that. It should be solid without id collisions. Wouldn't it be to late if I should fix it later?
I don't like that. It should be solid without id collisions. Wouldn't it be to late if I should fix it later?
Add files, connectors, and more
Model: Opus 4.7 Adaptive
Opus 4.7
Adaptive
Send message
Claude is AI and can make mistakes. Please double-check responses.
Claude is AI and can make mistakes. Please double-check responses.
Screenpipe sync · SH
Screenpipe sync
·
SH
Copy
Close
1
#!/bin/bash
2
# screenpipe_sync.sh
3
# Syncs Screenpipe SQLite data (vision + audio) to a NAS archive database.
4
# Append-only, no deletions.
5
#
6
# Key design points
7
# -----------------
8
# 1. Multi-install safe via install_id.
9
# Source IDs reset to 1 on every screenpipe reinstall. To avoid collisions
10
# in the NAS archive, every synced table gets an extra `install_id` column,
11
# and the logical primary key becomes (install_id, id) enforced by a
12
# unique index. The install_id is a UUID stored in
13
# ~/.screenpipe/.sync_install_id — wiping ~/.screenpipe/ (which is what
14
# happens on reinstall) discards it, so the next run generates a new one.
15
#
16
# 2. Schema-drift tolerant. If screenpipe migrations add new columns to the
17
# source DB, the NAS gets ALTER TABLE'd to match. Inserts use explicit
18
# column lists so positional mismatches can't occur.
19
#
20
# 3. FTS caveat. FTS tables in the NAS use source `id` as rowid. After a
21
# reinstall, INSERT OR IGNORE will silently skip rows whose id collides
22
# with a previous install's id, so FTS only reliably indexes the most
23
# recent install. Falls back to LIKE queries on the base tables for
24
# multi-install searches (which can filter by install_id).
25
#
26
# Usage
27
# -----
28
# ./screenpipe_sync.sh # syncs yesterday
29
# ./screenpipe_sync.sh 2026-04-15 # syncs a specific date
30
# ./screenpipe_sync.sh today # syncs today so far
31
# ./screenpipe_sync.sh --reset-install-id # rotate install_id and exit
32
# ./screenpipe_sync.sh --show-install-id # print install_id and exit
33
34
set
-euo
pipefail
35
36
# ─── CONFIG ───────────────────────────────────────────────────────────────────
37
DB_SRC
=
"${SCREENPIPE_DB:-$HOME/.screenpipe/db.sqlite}"
38
NAS_MOUNT
=
"${NAS_MOUNT:-/Volumes/screenpipe}"
39
NAS_DB
=
"$NAS_MOUNT/archive.db"
40
NAS_DATA
=
"$NAS_MOUNT/data"
41
LOG_FILE
=
"$HOME/.screenpipe/sync.log"
42
INSTALL_ID_FILE
=
"$HOME/.screenpipe/.sync_install_id"
43
44
# Sync table groups. Order matters for FK-ish references
45
# (parents before children).
46
VISION_TABLES
=(video_chunks frames elements ocr_text ui_events meetings)
47
AUDIO_TABLES
=(speakers speaker_embeddings audio_chunks audio_transcriptions audio_tags)
48
ALL_SYNC_TABLES
=(
"${VISION_TABLES[@]}"
"${AUDIO_TABLES[@]}"
)
49
# ──────────────────────────────────────────────────────────────────────────────
50
51
SCRIPT_START
=
$(date +%s)
52
53
# ─── HELPERS ──────────────────────────────────────────────────────────────────
54
log
() {
55
local
msg
=
"[$(date '+%Y-%m-%d %H:%M:%S')] $*"
56
echo
"$msg"
|
tee
-a
"$LOG_FILE"
57
}
58
59
step
() {
60
local
now
=
$(date +%s)
61
local
elapsed
=$((
now
-
SCRIPT_START
))
62
local
min
=$((
elapsed
/ 60 ))
63
local
sec
=$((
elapsed
% 60 ))
64
printf
"\n[+%02dm%02ds] ▶ %s\n"
"$min"
"$sec"
"$*"
|
tee
-a
"$LOG_FILE"
65
}
66
67
run_sqlite_heredoc
() {
68
local
label
=
"$1"
69
local
sql
=
"$2"
70
local
start
=
$(date +%s)
71
72
printf
" %-36s "
"$label"
73
74
sqlite3
"$DB_SRC"
<<<
"$sql"
&
75
local
pid
=
$
!
76...
|
21467
|
NULL
|
NULL
|
NULL
|
|
2382
|
NULL
|
0
|
2026-05-07T11:13:59.002551+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778152439002_m1.jpg...
|
iTerm2
|
NULL
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp(ahol§ Support Daily - in 47 m100% [DEV (docker)83Thu 7 May 14:13:58181₴6DOCKERLast login: Thu MayO ₴1DEV (docker)7 09:44:56 on ttys006H82APP (-zsh)-zsh• 84screenpipe*•$5-zshPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parentsPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parentslukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20773-fix-automated-reports-user-pilot-tracking) $ devroot@docker_lamp_1:/home/jiminny# php artisan crm:sync-opportunity --teamId=2 --from='2026-05-01 00:00:00*Syncing opportunity for HubspotYour HubSpotaccount has become disconnected. Please login to Jiminny to reconnect. skipping...root@docker_lamp_1:/home/jiminny# php artisan jiminny:token-info -A 1499 -RDEVaccess_tokenCFPAsBNZxoDp5kAcRyeB1QoE5SM7DSgNuYTFSAFoAYABo3tj9DHAAeAACNeR-JHgMxIZQLNQMl8kQEwrAgwACAkUAhIJBB4BAQEDBxiCiYwCIN7Y_Qwo0qwCMhTnG549n-YtNuc1jgj-2AsLPSmw3DoyQLNQM18kQEwrAiUACBkGawEFThwBARIBAQEEATEEAQEBAQEBAQEBAQUBEggBAQEBAY1access_token_expires_at= 2026-05-07 11:41:20refresh_token => d5ab04e2-2109-4c0b-b513-8cba1dd54371refresh_token_expires_at =root@docker_lamp_1:/home/jiminny#...
|
NULL
|
-8249185083358050119
|
NULL
|
click
|
ocr
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp(ahol§ Support Daily - in 47 m100% [DEV (docker)83Thu 7 May 14:13:58181₴6DOCKERLast login: Thu MayO ₴1DEV (docker)7 09:44:56 on ttys006H82APP (-zsh)-zsh• 84screenpipe*•$5-zshPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parentsPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parentslukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20773-fix-automated-reports-user-pilot-tracking) $ devroot@docker_lamp_1:/home/jiminny# php artisan crm:sync-opportunity --teamId=2 --from='2026-05-01 00:00:00*Syncing opportunity for HubspotYour HubSpotaccount has become disconnected. Please login to Jiminny to reconnect. skipping...root@docker_lamp_1:/home/jiminny# php artisan jiminny:token-info -A 1499 -RDEVaccess_tokenCFPAsBNZxoDp5kAcRyeB1QoE5SM7DSgNuYTFSAFoAYABo3tj9DHAAeAACNeR-JHgMxIZQLNQMl8kQEwrAgwACAkUAhIJBB4BAQEDBxiCiYwCIN7Y_Qwo0qwCMhTnG549n-YtNuc1jgj-2AsLPSmw3DoyQLNQM18kQEwrAiUACBkGawEFThwBARIBAQEEATEEAQEBAQEBAQEBAQUBEggBAQEBAY1access_token_expires_at= 2026-05-07 11:41:20refresh_token => d5ab04e2-2109-4c0b-b513-8cba1dd54371refresh_token_expires_at =root@docker_lamp_1:/home/jiminny#...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
13308
|
588
|
30
|
2026-05-09T15:18:29.746067+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778339909746_m2.jpg...
|
Firefox
|
DXP4800PLUS-B5F8 — Personal
|
True
|
nas.lakylak.xyz/desktop/?os=ugospro#/
|
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
Close tab
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
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
1.2
MB/s
72.1
KB/s
Files
Control Panel
Storage
App Center
Logs
Support
Task Manager
Music
Cloud Drives
Theater
Photos
Online Office
TextEdit
Virtual Machine
Downloads
DLNA
File Version Explorer
Security
Jellyfin-HT
SAN Manager
Vault
Snapshot
Comics
Sync & Backup
UGREEN AI
Recycle Bin
Control Panel
Search
Connection & Access
User Management
File Service
Device Connection
Domain/LDAP
Terminal
General
Hardware & Power
Time & Language
Network
Security
Indexing Service
Service
About
Update & Restore
Telnet
Enable
Enable
Port
23
Advanced settings
SSH
Enable
Enable
Port
22
Shut down automatically
6h later
Advanced settings
Function description
Use a terminal to log in and manage your system. When enabling this function, it is recommended to set a strong password for the login account and enable
auto block
auto block
to enhance system security.
Apply
Tips
Tips
SSH possesses advanced remote management feature, but enabling it for a long term will increase security risks (e.g. potential unauthorized access). To ensure NAS and data security, please only enable SSH when in need
Cancel
Enable...
|
[{"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":true},{"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":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.10139628,"top":0.28810853,"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":"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 (2) - 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 (2) - kovaliklukas@gmail.com - Gmail","depth":5,"bounds":{"left":0.013297873,"top":0.42298484,"width":0.07513298,"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":false},{"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":"AXRadioButton","text":"Select: transactions - 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":"Select: transactions - db - Adminer","depth":5,"bounds":{"left":0.013297873,"top":0.5865922,"width":0.061170213,"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":"AXStaticText","text":"","depth":18,"bounds":{"left":0.47706118,"top":0.06304868,"width":0.0066489363,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1.2","depth":16,"bounds":{"left":0.4247008,"top":0.06264964,"width":0.0051529254,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"MB/s","depth":16,"bounds":{"left":0.42985374,"top":0.06304868,"width":0.0063164895,"height":0.0075818035},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"72.1","depth":16,"bounds":{"left":0.4247008,"top":0.07222666,"width":0.0071476065,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"KB/s","depth":16,"bounds":{"left":0.4318484,"top":0.0726257,"width":0.005984043,"height":0.0075818035},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Files","depth":13,"bounds":{"left":0.13663563,"top":0.1707901,"width":0.009973404,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Control Panel","depth":13,"bounds":{"left":0.12749335,"top":0.2697526,"width":0.02825798,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Storage","depth":13,"bounds":{"left":0.13347739,"top":0.36871508,"width":0.016289894,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"App Center","depth":13,"bounds":{"left":0.12982048,"top":0.46767756,"width":0.023603724,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Logs","depth":13,"bounds":{"left":0.13663563,"top":0.5666401,"width":0.009973404,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Support","depth":13,"bounds":{"left":0.13347739,"top":0.66560256,"width":0.016289894,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Task Manager","depth":13,"bounds":{"left":0.12699468,"top":0.76456505,"width":0.02925532,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Music","depth":13,"bounds":{"left":0.13547207,"top":0.86352754,"width":0.012300532,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Cloud Drives","depth":13,"bounds":{"left":0.17619681,"top":0.1707901,"width":0.026595745,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Theater","depth":13,"bounds":{"left":0.18151596,"top":0.2697526,"width":0.015957447,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Photos","depth":13,"bounds":{"left":0.18218085,"top":0.36871508,"width":0.01462766,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online Office","depth":13,"bounds":{"left":0.17603059,"top":0.46767756,"width":0.026928192,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TextEdit","depth":13,"bounds":{"left":0.18118352,"top":0.5666401,"width":0.01662234,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Virtual Machine","depth":13,"bounds":{"left":0.17353724,"top":0.66560256,"width":0.031914894,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Downloads","depth":13,"bounds":{"left":0.17802526,"top":0.76456505,"width":0.022938829,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DLNA","depth":13,"bounds":{"left":0.18334441,"top":0.86352754,"width":0.012300532,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"File Version Explorer","depth":13,"bounds":{"left":0.2159242,"top":0.1707901,"width":0.04288564,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Security","depth":13,"bounds":{"left":0.22888963,"top":0.2697526,"width":0.016954787,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jellyfin-HT","depth":13,"bounds":{"left":0.22639628,"top":0.36871508,"width":0.021941489,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SAN Manager","depth":13,"bounds":{"left":0.22273937,"top":0.46767756,"width":0.02925532,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Vault","depth":13,"bounds":{"left":0.2322141,"top":0.5666401,"width":0.010305851,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Snapshot","depth":13,"bounds":{"left":0.22755983,"top":0.66560256,"width":0.019614361,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Comics","depth":13,"bounds":{"left":0.22955452,"top":0.76456505,"width":0.015625,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sync & Backup","depth":13,"bounds":{"left":0.2215758,"top":0.86352754,"width":0.03158245,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UGREEN AI","depth":13,"bounds":{"left":0.27244017,"top":0.1707901,"width":0.025598405,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Recycle Bin","depth":13,"bounds":{"left":0.27293882,"top":0.2697526,"width":0.024601065,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Control Panel","depth":13,"bounds":{"left":0.29787233,"top":0.19872306,"width":0.025930852,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.4431516,"top":0.19473264,"width":0.007978723,"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":"","depth":14,"bounds":{"left":0.44448137,"top":0.19792499,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":19,"bounds":{"left":0.17885639,"top":0.23463687,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Search","depth":18,"bounds":{"left":0.1861702,"top":0.22745411,"width":0.028922873,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Connection & Access","depth":19,"bounds":{"left":0.16522606,"top":0.27853152,"width":0.037898935,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Management","depth":21,"bounds":{"left":0.17519946,"top":0.31284916,"width":0.040059842,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"File Service","depth":21,"bounds":{"left":0.17519946,"top":0.35115722,"width":0.025930852,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Device Connection","depth":21,"bounds":{"left":0.17519946,"top":0.38946527,"width":0.025598405,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Domain/LDAP","depth":21,"bounds":{"left":0.17519946,"top":0.44692737,"width":0.031083776,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Terminal","depth":21,"bounds":{"left":0.17519946,"top":0.48523542,"width":0.019115692,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"General","depth":19,"bounds":{"left":0.16522606,"top":0.5243416,"width":0.01412899,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hardware & Power","depth":21,"bounds":{"left":0.17519946,"top":0.5586592,"width":0.04105718,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Time & Language","depth":21,"bounds":{"left":0.17519946,"top":0.5969673,"width":0.03873005,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Network","depth":21,"bounds":{"left":0.17519946,"top":0.63527536,"width":0.018284574,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Security","depth":21,"bounds":{"left":0.17519946,"top":0.6735834,"width":0.018284574,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Indexing Service","depth":21,"bounds":{"left":0.17519946,"top":0.7118915,"width":0.036901597,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Service","depth":19,"bounds":{"left":0.16522606,"top":0.7509976,"width":0.013297873,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"About","depth":21,"bounds":{"left":0.17519946,"top":0.7853152,"width":0.013464096,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Update & Restore","depth":21,"bounds":{"left":0.17519946,"top":0.8236233,"width":0.0390625,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Telnet","depth":18,"bounds":{"left":0.23786569,"top":0.2490024,"width":0.012466756,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Enable","depth":18,"bounds":{"left":0.25864363,"top":0.25019953,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Enable","depth":18,"bounds":{"left":0.26595744,"top":0.2490024,"width":0.014461436,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Port","depth":19,"bounds":{"left":0.265625,"top":0.27773345,"width":0.008477394,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"23","depth":20,"bounds":{"left":0.28108376,"top":0.27214685,"width":0.06781915,"height":0.023942538},"on_screen":true,"value":"23","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Advanced settings","depth":18,"bounds":{"left":0.25864363,"top":0.30766162,"width":0.0546875,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SSH","depth":18,"bounds":{"left":0.24069148,"top":0.36711892,"width":0.009640957,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":20,"bounds":{"left":0.25897607,"top":0.36911413,"width":0.0039893617,"height":0.009577015},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Enable","depth":18,"bounds":{"left":0.25864363,"top":0.36831605,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Enable","depth":18,"bounds":{"left":0.26595744,"top":0.36711892,"width":0.014461436,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Port","depth":19,"bounds":{"left":0.265625,"top":0.39584997,"width":0.008477394,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"22","depth":20,"bounds":{"left":0.3229721,"top":0.39026338,"width":0.06781915,"height":0.023942538},"on_screen":true,"value":"22","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Shut down automatically","depth":19,"bounds":{"left":0.265625,"top":0.4309657,"width":0.05036569,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6h later","depth":22,"bounds":{"left":0.3229721,"top":0.43176377,"width":0.013297873,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.3854721,"top":0.4309657,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.39644283,"top":0.43136472,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Advanced settings","depth":18,"bounds":{"left":0.25864363,"top":0.45969674,"width":0.0546875,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Function description","depth":17,"bounds":{"left":0.23836437,"top":0.52673584,"width":0.046043884,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Use a terminal to log in and manage your system. When enabling this function, it is recommended to set a strong password for the login account and enable","depth":17,"bounds":{"left":0.23836437,"top":0.5450918,"width":0.19896941,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"auto block","depth":17,"bounds":{"left":0.31432846,"top":0.556664,"width":0.018284574,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"auto block","depth":18,"bounds":{"left":0.31432846,"top":0.556664,"width":0.018284574,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to enhance system security.","depth":17,"bounds":{"left":0.33261302,"top":0.556664,"width":0.050199468,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Apply","depth":18,"bounds":{"left":0.4175532,"top":0.782921,"width":0.02825798,"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":"","depth":23,"bounds":{"left":0.23686835,"top":0.44892257,"width":0.0066489363,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Tips","depth":21,"bounds":{"left":0.24750665,"top":0.44493216,"width":0.013464096,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Tips","depth":22,"bounds":{"left":0.24750665,"top":0.44692737,"width":0.013464096,"height":0.018355945},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SSH possesses advanced remote management feature, but enabling it for a long term will increase security risks (e.g. potential unauthorized access). To ensure NAS and data security, please only enable SSH when in need","depth":21,"bounds":{"left":0.23686835,"top":0.48244214,"width":0.13680187,"height":0.065442935},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Cancel","depth":19,"bounds":{"left":0.31067154,"top":0.5766161,"width":0.031083776,"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":"Enable","depth":19,"bounds":{"left":0.34574467,"top":0.5766161,"width":0.031083776,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-8249184623228913989
|
-8484350503905391345
|
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
Close tab
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
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
1.2
MB/s
72.1
KB/s
Files
Control Panel
Storage
App Center
Logs
Support
Task Manager
Music
Cloud Drives
Theater
Photos
Online Office
TextEdit
Virtual Machine
Downloads
DLNA
File Version Explorer
Security
Jellyfin-HT
SAN Manager
Vault
Snapshot
Comics
Sync & Backup
UGREEN AI
Recycle Bin
Control Panel
Search
Connection & Access
User Management
File Service
Device Connection
Domain/LDAP
Terminal
General
Hardware & Power
Time & Language
Network
Security
Indexing Service
Service
About
Update & Restore
Telnet
Enable
Enable
Port
23
Advanced settings
SSH
Enable
Enable
Port
22
Shut down automatically
6h later
Advanced settings
Function description
Use a terminal to log in and manage your system. When enabling this function, it is recommended to set a strong password for the login account and enable
auto block
auto block
to enhance system security.
Apply
Tips
Tips
SSH possesses advanced remote management feature, but enabling it for a long term will increase security risks (e.g. potential unauthorized access). To ensure NAS and data security, please only enable SSH when in need
Cancel
Enable...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
13309
|
587
|
38
|
2026-05-09T15:18:29.746045+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778339909746_m1.jpg...
|
Firefox
|
DXP4800PLUS-B5F8 — Personal
|
True
|
nas.lakylak.xyz/desktop/?os=ugospro#/
|
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
Close tab
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
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
1.2
MB/s
72.1
KB/s
Files
Control Panel
Storage
App Center
Logs
Support
Task Manager
Music
Cloud Drives
Theater
Photos
Online Office
TextEdit
Virtual Machine
Downloads
DLNA
File Version Explorer
Security
Jellyfin-HT
SAN Manager
Vault
Snapshot
Comics
Sync & Backup
UGREEN AI
Recycle Bin
Control Panel
Search
Connection & Access
User Management
File Service
Device Connection
Domain/LDAP
Terminal
General
Hardware & Power
Time & Language
Network
Security
Indexing Service
Service
About
Update & Restore
Telnet
Enable
Enable
Port
23
Advanced settings
SSH
Enable
Enable
Port
22
Shut down automatically
6h later
Advanced settings
Function description
Use a terminal to log in and manage your system. When enabling this function, it is recommended to set a strong password for the login account and enable
auto block
auto block
to enhance system security.
Apply
Tips
Tips
SSH possesses advanced remote management feature, but enabling it for a long term will increase security risks (e.g. potential unauthorized access). To ensure NAS and data security, please only enable SSH when in need
Cancel
Enable...
|
[{"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":true},{"role":"AXStaticText","text":"DXP4800PLUS-B5F8","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":"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":false},{"role":"AXStaticText","text":"Finance Hub","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"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":"AXStaticText","text":"","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1.2","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"MB/s","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"72.1","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"KB/s","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Files","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Control Panel","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Storage","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"App Center","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Logs","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Support","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Task Manager","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Music","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Cloud Drives","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Theater","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Photos","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online Office","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TextEdit","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Virtual Machine","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Downloads","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DLNA","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"File Version Explorer","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Security","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jellyfin-HT","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SAN Manager","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Vault","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Snapshot","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Comics","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sync & Backup","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UGREEN AI","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Recycle Bin","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Control Panel","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":19,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Search","depth":18,"on_screen":true,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Connection & Access","depth":19,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Management","depth":21,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"File Service","depth":21,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Device Connection","depth":21,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Domain/LDAP","depth":21,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Terminal","depth":21,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"General","depth":19,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hardware & Power","depth":21,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Time & Language","depth":21,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Network","depth":21,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Security","depth":21,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Indexing Service","depth":21,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Service","depth":19,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"About","depth":21,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Update & Restore","depth":21,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Telnet","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Enable","depth":18,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Enable","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Port","depth":19,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"23","depth":20,"on_screen":true,"value":"23","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Advanced settings","depth":18,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SSH","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":20,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Enable","depth":18,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Enable","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Port","depth":19,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"22","depth":20,"on_screen":true,"value":"22","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Shut down automatically","depth":19,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6h later","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Advanced settings","depth":18,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Function description","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Use a terminal to log in and manage your system. When enabling this function, it is recommended to set a strong password for the login account and enable","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"auto block","depth":17,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"auto block","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to enhance system security.","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Apply","depth":18,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":23,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Tips","depth":21,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Tips","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SSH possesses advanced remote management feature, but enabling it for a long term will increase security risks (e.g. potential unauthorized access). To ensure NAS and data security, please only enable SSH when in need","depth":21,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Cancel","depth":19,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Enable","depth":19,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false}]...
|
-8249184623228913989
|
-8484350503905391345
|
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
Close tab
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
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
1.2
MB/s
72.1
KB/s
Files
Control Panel
Storage
App Center
Logs
Support
Task Manager
Music
Cloud Drives
Theater
Photos
Online Office
TextEdit
Virtual Machine
Downloads
DLNA
File Version Explorer
Security
Jellyfin-HT
SAN Manager
Vault
Snapshot
Comics
Sync & Backup
UGREEN AI
Recycle Bin
Control Panel
Search
Connection & Access
User Management
File Service
Device Connection
Domain/LDAP
Terminal
General
Hardware & Power
Time & Language
Network
Security
Indexing Service
Service
About
Update & Restore
Telnet
Enable
Enable
Port
23
Advanced settings
SSH
Enable
Enable
Port
22
Shut down automatically
6h later
Advanced settings
Function description
Use a terminal to log in and manage your system. When enabling this function, it is recommended to set a strong password for the login account and enable
auto block
auto block
to enhance system security.
Apply
Tips
Tips
SSH possesses advanced remote management feature, but enabling it for a long term will increase security risks (e.g. potential unauthorized access). To ensure NAS and data security, please only enable SSH when in need
Cancel
Enable...
|
13306
|
NULL
|
NULL
|
NULL
|
|
14156
|
630
|
27
|
2026-05-09T17:02:04.775124+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778346124775_m2.jpg...
|
Firefox
|
Nginx Proxy Manager — Personal
|
True
|
http://192.168.0.242:81/nginx/proxy
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Pull requests · screenpipe/screenpipe · GitHub
Clo Pull requests · screenpipe/screenpipe · GitHub
Close tab
DNS / Nameservers | Hostinger
Close tab
Nginx Proxy Manager
Close tab
Screenpipe — Archive
Close tab
SQLite Web: archive.db
Close tab
SQLite Web: db.sqlite
Close tab
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
Close tab
DXP4800PLUS-B5F8
Close tab
AFFiNE - All In One KnowledgeOS
Close tab
All docs · AFFiNE
Close tab
Payments Logger
Close tab
Your old PC can run Windows 11 in a VM, but not on bare metal - [EMAIL] - Gmail
Close tab
Location Logger
Close tab
Finance Hub
Close tab
Finance Hub
Close tab
Select: transactions - db - Adminer
Close tab
Claude Code | Claude Platform
Close tab
Claude
Close tab
lakylak/finance-hub - finance-hub - Gitea: Git with a cup of tea
Close tab
Applications - Admin - authentik
Close tab
New Tab
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Customize sidebar
Nginx Proxy Manager
Nginx Proxy Manager
Admin Administrator
Admin
Administrator
Dashboard
Dashboard
Hosts
Hosts
Access Lists
Access Lists
SSL Certificates
SSL Certificates
Users
Users
Audit Log
Audit Log
Settings
Settings
Proxy Hosts
Proxy Hosts
Search Host…
Add Proxy Host
Add Proxy Host
SOURCE
DESTINATION
SSL
ACCESS
STATUS
ai.chat.lakylak.xyz
Created: 10th March 2026
http://[IP_ADDRESS]:11000
Let's Encrypt
Public
Online
app.lakylak.xyz
Created: 19th July 2025
http://[IP_ADDRESS]:18083
Let's Encrypt
Public
Online
app.payments.lakylak.xyz
Created: 14th February 2026
http://[IP_ADDRESS]:5174
Let's Encrypt
Public
Online
app.screenpipe.lakylak.xyz
Created: 27th April 2026
http://[IP_ADDRESS]:8766
Let's Encrypt
Public
Online
audiobook.lakylak.xyz
Created: 15th June 2025
http://192.168..242:13378
Let's Encrypt
Public
Online
auth.lakylak.xyz
Created: 30th March 2026
http://[IP_ADDRESS]:9100
Let's Encrypt
Public
Online
backup.lakylak.xyz
Created: 10th July 2025
http://[IP_ADDRESS]:9999
Let's Encrypt
Public
Online
beszel.lakylak.xyz
Created: 6th December 2025
http://[IP_ADDRESS]:8095
Let's Encrypt
Public
Online
bitwarden.lakylak.xyz
Created: 16th June 2025
http://[IP_ADDRESS]:9890
Let's Encrypt
Public
Online
book.lakylak.xyz
Created: 31st October 2025
http://[IP_ADDRESS]:6060
Let's Encrypt
Public
Online
crm.lakylak.xyz
Created: 25th July 2025
http://[IP_ADDRESS]:3353
Let's Encrypt
Public
Online
dawarich.lakylak.xyz
Created: 25th August 2025
http://[IP_ADDRESS]:3000
Let's Encrypt
Public
Online
db.screenpipe.lakylak.xyz
Created: 27th April 2026
http://[IP_ADDRESS]:8767
Let's Encrypt
Public
Online
dsk-uploader.lakylak.xyz
Created: 15th August 2025
http://[IP_ADDRESS]:8502
Let's Encrypt
Public
Online
finance-hub.lakylak.xyz
Created: 8th May 2026
http://[IP_ADDRESS]:5175
Let's Encrypt
Public
Online
gitea.lakylak.xyz
Created: 18th July 2025
http://[IP_ADDRESS]:3052
Let's Encrypt
Public
Online
hydra.lakylak.xyz
Created: 29th March 2026
http://[IP_ADDRESS]:4444
Let's Encrypt
Public
Online
images.lakylak.xyz
Created: 17th June 2025
http://[IP_ADDRESS]:3474
Let's Encrypt
Public
Online
immich.lakylak.xyz
Created: 15th June 2025
http://[IP_ADDRESS]:8212
Let's Encrypt
Public
Online
jellyfin.lakylak.xyz
Created: 15th June 2025
http://[IP_ADDRESS]:8096
Let's Encrypt
Public
Online
lakylak.xyz
Created: 15th June 2025
http://[IP_ADDRESS]:9999
Let's Encrypt
Public
Online
linkwarden.lakylak.xyz
Created: 13th December 2025
http://[IP_ADDRESS]:7461
Let's Encrypt
Public
Online
location-tracker.lakylak.xyz
Created: 30th August 2025
http://[IP_ADDRESS]:8050
Let's Encrypt
Public
Online
log.lakylak.xyz
Created: 23rd September 2025
http://[IP_ADDRESS]:18084
Let's Encrypt
Public
Online
login.lakylak.xyz
Created: 29th March 2026
http://[IP_ADDRESS]:4446
Let's Encrypt
Public
Online
mcp.location.lakylak.xyz
Created: 15th March 2026
http://[IP_ADDRESS]:8052
Let's Encrypt
Public
Online
n8n.lakylak.xyz
Created: 17th July 2025
http://[IP_ADDRESS]:5678
Let's Encrypt
Public
Online
nas.lakylak.xyz
Created: 28th July 2025
http://[IP_ADDRESS]:9999
Let's Encrypt
Public
Online
notes.lakylak.xyz
Created: 31st October 2025
http://[IP_ADDRESS]:8085
Let's Encrypt
Public
Online
obsidian.lakylak.xyz
Created: 17th June 2025
http://[IP_ADDRESS]:3421
Let's Encrypt
Public
Online
outfit.lakylak.xyz
Created: 25th March 2026
http://[IP_ADDRESS]:8667
Let's Encrypt
Public
Online
owntracks.lakylak.xyz
Created: 12th August 2025
http://[IP_ADDRESS]:8083
Let's Encrypt
Public
Online
paperless.lakylak.xyz
Created: 25th October 2025
http://[IP_ADDRESS]:8777
Let's Encrypt
Public
Online
payments.lakylak.xyz
Created: 14th February 2026
http://[IP_ADDRESS]:3010
Let's Encrypt
Public
Online
pdf.lakylak.xyz
Created: 19th June 2025
http://[IP_ADDRESS]:7890
Let's Encrypt
Public
Online
portainer.lakylak.xyz
Created: 15th June 2025
http://[IP_ADDRESS]:9000
Let's Encrypt
Public
Online
sqlite.screenpipe.lakylak.xyz
Created: 27th April 2026
http://[IP_ADDRESS]:8768
Let's Encrypt
Public
Online
todo.lakylak.xyz
Created: 16th March 2026
http://reminder-app:8000
Let's Encrypt
Public
Online
tree.lakylak.xyz
Created: 19th December 2025
http://[IP_ADDRESS]:8200
Let's Encrypt
Public
Online
trilium.lakylak.xyz
Created: 24th December 2025
http://[IP_ADDRESS]:4292
Let's Encrypt
Public
Online
tube.lakylak.xyz
Created: 3rd December 2025
http://[IP_ADDRESS]:8770...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Pull requests · screenpipe/screenpipe · GitHub","depth":4,"bounds":{"left":0.0,"top":0.0518755,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.0518755,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"DNS / Nameservers | Hostinger","depth":4,"bounds":{"left":0.0,"top":0.08459697,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.08459697,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Nginx Proxy Manager","depth":4,"bounds":{"left":0.0,"top":0.11731844,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.11731844,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Screenpipe — Archive","depth":4,"bounds":{"left":0.0,"top":0.15003991,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.15003991,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"SQLite Web: archive.db","depth":4,"bounds":{"left":0.0,"top":0.18276137,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.18276137,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"SQLite Web: db.sqlite","depth":4,"bounds":{"left":0.0,"top":0.21548285,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.21548285,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub","depth":4,"bounds":{"left":0.0,"top":0.2482043,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.2482043,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"bounds":{"left":0.0,"top":0.28092578,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.28092578,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"AFFiNE - All In One KnowledgeOS","depth":4,"bounds":{"left":0.0,"top":0.31364724,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.31364724,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"All docs · AFFiNE","depth":4,"bounds":{"left":0.0,"top":0.3463687,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.3463687,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Payments Logger","depth":4,"bounds":{"left":0.0,"top":0.3790902,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.3790902,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Your old PC can run Windows 11 in a VM, but not on bare metal - kovaliklukas@gmail.com - Gmail","depth":4,"bounds":{"left":0.0,"top":0.41181165,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.41181165,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Location Logger","depth":4,"bounds":{"left":0.0,"top":0.4445331,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.4445331,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Finance Hub","depth":4,"bounds":{"left":0.0,"top":0.4772546,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.4772546,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Finance Hub","depth":4,"bounds":{"left":0.0,"top":0.509976,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.509976,"width":0.004986702,"height":0.011971269},"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,"bounds":{"left":0.0,"top":0.54269755,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.54269755,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Claude Code | Claude Platform","depth":4,"bounds":{"left":0.0,"top":0.575419,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.575419,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Claude","depth":4,"bounds":{"left":0.0,"top":0.60814047,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.60814047,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"lakylak/finance-hub - finance-hub - Gitea: Git with a cup of tea","depth":4,"bounds":{"left":0.0,"top":0.6408619,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.6408619,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Applications - Admin - authentik","depth":4,"bounds":{"left":0.0,"top":0.6735834,"width":0.016123671,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0006648936,"top":0.6735834,"width":0.004986702,"height":0.011971269},"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.0028257978,"top":0.70790106,"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":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.8547486,"width":0.016123671,"height":0.0311253},"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.8858739,"width":0.016123671,"height":0.027533919},"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.9134078,"width":0.016123671,"height":0.02793296},"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.0,"top":0.9413408,"width":0.016123671,"height":0.027533919},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.9688747,"width":0.016123671,"height":0.0311253},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Nginx Proxy Manager","depth":8,"bounds":{"left":0.09391622,"top":0.061452515,"width":0.06648936,"height":0.03471668},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Nginx Proxy Manager","depth":9,"bounds":{"left":0.10455452,"top":0.06783719,"width":0.055851065,"height":0.018355945},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Admin Administrator","depth":8,"bounds":{"left":0.4424867,"top":0.06584198,"width":0.042386968,"height":0.02593775},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Admin","depth":10,"bounds":{"left":0.45977393,"top":0.06424581,"width":0.013630319,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Administrator","depth":11,"bounds":{"left":0.45977393,"top":0.07980846,"width":0.025099734,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":" Dashboard","depth":10,"bounds":{"left":0.09391622,"top":0.10654429,"width":0.028590426,"height":0.044293694},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":12,"bounds":{"left":0.09391622,"top":0.122505985,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dashboard","depth":11,"bounds":{"left":0.09990027,"top":0.12051077,"width":0.022606382,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":" Hosts","depth":10,"bounds":{"left":0.13048537,"top":0.10654429,"width":0.01761968,"height":0.044293694},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":12,"bounds":{"left":0.13048537,"top":0.122505985,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hosts","depth":11,"bounds":{"left":0.13646941,"top":0.12051077,"width":0.011635638,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":" Access Lists","depth":10,"bounds":{"left":0.15608378,"top":0.10654429,"width":0.030086435,"height":0.044293694},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":12,"bounds":{"left":0.15608378,"top":0.122505985,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Access Lists","depth":11,"bounds":{"left":0.16206782,"top":0.12051077,"width":0.024102394,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":" SSL Certificates","depth":10,"bounds":{"left":0.19414894,"top":0.10654429,"width":0.038231384,"height":0.044293694},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":12,"bounds":{"left":0.19414894,"top":0.122505985,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SSL Certificates","depth":11,"bounds":{"left":0.20013298,"top":0.12051077,"width":0.032247342,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":" Users","depth":10,"bounds":{"left":0.24035904,"top":0.10654429,"width":0.017453458,"height":0.044293694},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":12,"bounds":{"left":0.24035904,"top":0.122505985,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Users","depth":11,"bounds":{"left":0.24634309,"top":0.12051077,"width":0.011469414,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":" Audit Log","depth":10,"bounds":{"left":0.26579124,"top":0.10654429,"width":0.025598405,"height":0.044293694},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":12,"bounds":{"left":0.26579124,"top":0.122505985,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Audit Log","depth":11,"bounds":{"left":0.27177528,"top":0.12051077,"width":0.019614361,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":" Settings","depth":10,"bounds":{"left":0.29936835,"top":0.10654429,"width":0.022938829,"height":0.044293694},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":12,"bounds":{"left":0.29936835,"top":0.122505985,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Settings","depth":11,"bounds":{"left":0.3053524,"top":0.12051077,"width":0.016954787,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Proxy Hosts","depth":9,"bounds":{"left":0.1022274,"top":0.1839585,"width":0.029089095,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Proxy Hosts","depth":10,"bounds":{"left":0.1022274,"top":0.18355946,"width":0.029089095,"height":0.018355945},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":11,"bounds":{"left":0.36319813,"top":0.1867518,"width":0.004986702,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Search Host…","depth":10,"bounds":{"left":0.35904256,"top":0.18156424,"width":0.06898271,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"","depth":9,"bounds":{"left":0.43068483,"top":0.18156424,"width":0.011469414,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":10,"bounds":{"left":0.43367687,"top":0.1867518,"width":0.005485372,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add Proxy Host","depth":9,"bounds":{"left":0.44481382,"top":0.18156424,"width":0.034408245,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add Proxy Host","depth":10,"bounds":{"left":0.44780585,"top":0.1859537,"width":0.028424202,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SOURCE","depth":12,"bounds":{"left":0.12084442,"top":0.22306465,"width":0.016289894,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DESTINATION","depth":12,"bounds":{"left":0.22207446,"top":0.22306465,"width":0.02642952,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SSL","depth":12,"bounds":{"left":0.32413563,"top":0.22306465,"width":0.0071476065,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACCESS","depth":12,"bounds":{"left":0.3801529,"top":0.22306465,"width":0.01512633,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"STATUS","depth":12,"bounds":{"left":0.41722074,"top":0.22306465,"width":0.014960106,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ai.chat.lakylak.xyz","depth":12,"bounds":{"left":0.12350399,"top":0.25897846,"width":0.03025266,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 10th March 2026","depth":13,"bounds":{"left":0.12084442,"top":0.28052673,"width":0.045877658,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:11000","depth":13,"bounds":{"left":0.22207446,"top":0.26735833,"width":0.055518616,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.32413563,"top":0.26735833,"width":0.026928192,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.3801529,"top":0.26735833,"width":0.013131649,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.421875,"top":0.26735833,"width":0.014793883,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.4715758,"top":0.26735833,"width":0.004986702,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.4715758,"top":0.26855546,"width":0.004986702,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.lakylak.xyz","depth":12,"bounds":{"left":0.12350399,"top":0.31843576,"width":0.02543218,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 19th July 2025","depth":13,"bounds":{"left":0.12084442,"top":0.33998403,"width":0.042386968,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:18083","depth":13,"bounds":{"left":0.22207446,"top":0.3272147,"width":0.055518616,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.32413563,"top":0.3272147,"width":0.026928192,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.3801529,"top":0.3272147,"width":0.013131649,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.421875,"top":0.3272147,"width":0.014793883,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.4715758,"top":0.3272147,"width":0.004986702,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.4715758,"top":0.32841182,"width":0.004986702,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.payments.lakylak.xyz","depth":12,"bounds":{"left":0.12350399,"top":0.37789306,"width":0.04288564,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 14th February 2026","depth":13,"bounds":{"left":0.12084442,"top":0.39944133,"width":0.05119681,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:5174","depth":13,"bounds":{"left":0.22207446,"top":0.386672,"width":0.053025264,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.32413563,"top":0.386672,"width":0.026928192,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.3801529,"top":0.386672,"width":0.013131649,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.421875,"top":0.386672,"width":0.014793883,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.4715758,"top":0.386672,"width":0.004986702,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.4715758,"top":0.38786912,"width":0.004986702,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.screenpipe.lakylak.xyz","depth":12,"bounds":{"left":0.12350399,"top":0.43774942,"width":0.04488032,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 27th April 2026","depth":13,"bounds":{"left":0.12084442,"top":0.4592977,"width":0.043218084,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8766","depth":13,"bounds":{"left":0.22207446,"top":0.4461293,"width":0.053025264,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.32413563,"top":0.4461293,"width":0.026928192,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.3801529,"top":0.4461293,"width":0.013131649,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.421875,"top":0.4461293,"width":0.014793883,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.4715758,"top":0.4461293,"width":0.004986702,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.4715758,"top":0.44732642,"width":0.004986702,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"audiobook.lakylak.xyz","depth":12,"bounds":{"left":0.12350399,"top":0.49720672,"width":0.03723404,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 15th June 2025","depth":13,"bounds":{"left":0.12084442,"top":0.51875496,"width":0.043716755,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168..242:13378","depth":13,"bounds":{"left":0.22207446,"top":0.5059856,"width":0.053025264,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.32413563,"top":0.5059856,"width":0.026928192,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.3801529,"top":0.5059856,"width":0.013131649,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.421875,"top":0.5059856,"width":0.014793883,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.4715758,"top":0.5059856,"width":0.004986702,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.4715758,"top":0.5071828,"width":0.004986702,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"auth.lakylak.xyz","depth":12,"bounds":{"left":0.12350399,"top":0.556664,"width":0.026761968,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 30th March 2026","depth":13,"bounds":{"left":0.12084442,"top":0.5786113,"width":0.045877658,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:9100","depth":13,"bounds":{"left":0.22207446,"top":0.5654429,"width":0.053025264,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.32413563,"top":0.5654429,"width":0.026928192,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.3801529,"top":0.5654429,"width":0.013131649,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.421875,"top":0.5654429,"width":0.014793883,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.4715758,"top":0.5654429,"width":0.004986702,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.4715758,"top":0.5666401,"width":0.004986702,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"backup.lakylak.xyz","depth":12,"bounds":{"left":0.12350399,"top":0.61652035,"width":0.03125,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 10th July 2025","depth":13,"bounds":{"left":0.12084442,"top":0.6380686,"width":0.042386968,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.243:9999","depth":13,"bounds":{"left":0.22207446,"top":0.6249002,"width":0.053025264,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.32413563,"top":0.6249002,"width":0.026928192,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.3801529,"top":0.6249002,"width":0.013131649,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.421875,"top":0.6249002,"width":0.014793883,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.4715758,"top":0.6249002,"width":0.004986702,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.4715758,"top":0.6260974,"width":0.004986702,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"beszel.lakylak.xyz","depth":12,"bounds":{"left":0.12350399,"top":0.67597765,"width":0.029587766,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 6th December 2025","depth":13,"bounds":{"left":0.12084442,"top":0.6975259,"width":0.05119681,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8095","depth":13,"bounds":{"left":0.22207446,"top":0.6847566,"width":0.053025264,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.32413563,"top":0.6847566,"width":0.026928192,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.3801529,"top":0.6847566,"width":0.013131649,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.421875,"top":0.6847566,"width":0.014793883,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.4715758,"top":0.6847566,"width":0.004986702,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.4715758,"top":0.68595374,"width":0.004986702,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"bitwarden.lakylak.xyz","depth":12,"bounds":{"left":0.12350399,"top":0.73543495,"width":0.036236703,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 16th June 2025","depth":13,"bounds":{"left":0.12084442,"top":0.7573823,"width":0.043716755,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:9890","depth":13,"bounds":{"left":0.22207446,"top":0.7442139,"width":0.053025264,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.32413563,"top":0.7442139,"width":0.026928192,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.3801529,"top":0.7442139,"width":0.013131649,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.421875,"top":0.7442139,"width":0.014793883,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.4715758,"top":0.7442139,"width":0.004986702,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.4715758,"top":0.74541104,"width":0.004986702,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"book.lakylak.xyz","depth":12,"bounds":{"left":0.12350399,"top":0.7952913,"width":0.027593086,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 31st October 2025","depth":13,"bounds":{"left":0.12084442,"top":0.8168396,"width":0.04886968,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:6060","depth":13,"bounds":{"left":0.22207446,"top":0.8036712,"width":0.053025264,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.32413563,"top":0.8036712,"width":0.026928192,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.3801529,"top":0.8036712,"width":0.013131649,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.421875,"top":0.8036712,"width":0.014793883,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.4715758,"top":0.8036712,"width":0.004986702,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.4715758,"top":0.80486834,"width":0.004986702,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crm.lakylak.xyz","depth":12,"bounds":{"left":0.12350399,"top":0.8547486,"width":0.025598405,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 25th July 2025","depth":13,"bounds":{"left":0.12084442,"top":0.8762969,"width":0.042386968,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:3353","depth":13,"bounds":{"left":0.22207446,"top":0.86352754,"width":0.053025264,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.32413563,"top":0.86352754,"width":0.026928192,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.3801529,"top":0.86352754,"width":0.013131649,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.421875,"top":0.86352754,"width":0.014793883,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.4715758,"top":0.86352754,"width":0.004986702,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.4715758,"top":0.86472464,"width":0.004986702,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dawarich.lakylak.xyz","depth":12,"bounds":{"left":0.12350399,"top":0.91460496,"width":0.034408245,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 25th August 2025","depth":13,"bounds":{"left":0.12084442,"top":0.93615323,"width":0.04720745,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:3000","depth":13,"bounds":{"left":0.22207446,"top":0.92298484,"width":0.053025264,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.32413563,"top":0.92298484,"width":0.026928192,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.3801529,"top":0.92298484,"width":0.013131649,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.421875,"top":0.92298484,"width":0.014793883,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.4715758,"top":0.92298484,"width":0.004986702,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.4715758,"top":0.92418194,"width":0.004986702,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"db.screenpipe.lakylak.xyz","depth":12,"bounds":{"left":0.12350399,"top":0.97406226,"width":0.04288564,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 27th April 2026","depth":13,"bounds":{"left":0.12084442,"top":0.99561054,"width":0.043218084,"height":0.004389465},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8767","depth":13,"bounds":{"left":0.22207446,"top":0.9828412,"width":0.053025264,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.32413563,"top":0.9828412,"width":0.026928192,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.3801529,"top":0.9828412,"width":0.013131649,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.421875,"top":0.9828412,"width":0.014793883,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.4715758,"top":0.9828412,"width":0.004986702,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.4715758,"top":0.9840383,"width":0.004986702,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dsk-uploader.lakylak.xyz","depth":12,"bounds":{"left":0.12350399,"top":1.0,"width":0.04089096,"height":-0.033519506},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 15th August 2025","depth":13,"bounds":{"left":0.12084442,"top":1.0,"width":0.04720745,"height":-0.055067778},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8502","depth":13,"bounds":{"left":0.22207446,"top":1.0,"width":0.053025264,"height":-0.042298436},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.32413563,"top":1.0,"width":0.026928192,"height":-0.042298436},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.3801529,"top":1.0,"width":0.013131649,"height":-0.042298436},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.421875,"top":1.0,"width":0.014793883,"height":-0.042298436},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.4715758,"top":1.0,"width":0.004986702,"height":-0.042298436},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.4715758,"top":1.0,"width":0.004986702,"height":-0.043495655},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"finance-hub.lakylak.xyz","depth":12,"bounds":{"left":0.12350399,"top":1.0,"width":0.0390625,"height":-0.09337592},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 8th May 2026","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:5175","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"gitea.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 18th July 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:3052","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"hydra.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 29th March 2026","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:4444","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"images.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 17th June 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:3474","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"immich.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 15th June 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8212","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jellyfin.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 15th June 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8096","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 15th June 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:9999","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"linkwarden.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 13th December 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:7461","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"location-tracker.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 30th August 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8050","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"log.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 23rd September 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:18084","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"login.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 29th March 2026","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:4446","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"mcp.location.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 15th March 2026","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8052","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"n8n.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 17th July 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:5678","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"nas.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 28th July 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:9999","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"notes.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 31st October 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8085","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"obsidian.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 17th June 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:3421","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"outfit.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 25th March 2026","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8667","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"owntracks.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 12th August 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8083","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"paperless.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 25th October 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8777","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"payments.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 14th February 2026","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:3010","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"pdf.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 19th June 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:7890","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"portainer.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 15th June 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:9000","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"sqlite.screenpipe.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 27th April 2026","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8768","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"todo.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 16th March 2026","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://reminder-app:8000","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"tree.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 19th December 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8200","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"trilium.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 24th December 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:4292","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"tube.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 3rd December 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8770","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8248863909361935441
|
-4931691133008957121
|
visual_change
|
accessibility
|
NULL
|
Pull requests · screenpipe/screenpipe · GitHub
Clo Pull requests · screenpipe/screenpipe · GitHub
Close tab
DNS / Nameservers | Hostinger
Close tab
Nginx Proxy Manager
Close tab
Screenpipe — Archive
Close tab
SQLite Web: archive.db
Close tab
SQLite Web: db.sqlite
Close tab
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
Close tab
DXP4800PLUS-B5F8
Close tab
AFFiNE - All In One KnowledgeOS
Close tab
All docs · AFFiNE
Close tab
Payments Logger
Close tab
Your old PC can run Windows 11 in a VM, but not on bare metal - [EMAIL] - Gmail
Close tab
Location Logger
Close tab
Finance Hub
Close tab
Finance Hub
Close tab
Select: transactions - db - Adminer
Close tab
Claude Code | Claude Platform
Close tab
Claude
Close tab
lakylak/finance-hub - finance-hub - Gitea: Git with a cup of tea
Close tab
Applications - Admin - authentik
Close tab
New Tab
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Customize sidebar
Nginx Proxy Manager
Nginx Proxy Manager
Admin Administrator
Admin
Administrator
Dashboard
Dashboard
Hosts
Hosts
Access Lists
Access Lists
SSL Certificates
SSL Certificates
Users
Users
Audit Log
Audit Log
Settings
Settings
Proxy Hosts
Proxy Hosts
Search Host…
Add Proxy Host
Add Proxy Host
SOURCE
DESTINATION
SSL
ACCESS
STATUS
ai.chat.lakylak.xyz
Created: 10th March 2026
http://[IP_ADDRESS]:11000
Let's Encrypt
Public
Online
app.lakylak.xyz
Created: 19th July 2025
http://[IP_ADDRESS]:18083
Let's Encrypt
Public
Online
app.payments.lakylak.xyz
Created: 14th February 2026
http://[IP_ADDRESS]:5174
Let's Encrypt
Public
Online
app.screenpipe.lakylak.xyz
Created: 27th April 2026
http://[IP_ADDRESS]:8766
Let's Encrypt
Public
Online
audiobook.lakylak.xyz
Created: 15th June 2025
http://192.168..242:13378
Let's Encrypt
Public
Online
auth.lakylak.xyz
Created: 30th March 2026
http://[IP_ADDRESS]:9100
Let's Encrypt
Public
Online
backup.lakylak.xyz
Created: 10th July 2025
http://[IP_ADDRESS]:9999
Let's Encrypt
Public
Online
beszel.lakylak.xyz
Created: 6th December 2025
http://[IP_ADDRESS]:8095
Let's Encrypt
Public
Online
bitwarden.lakylak.xyz
Created: 16th June 2025
http://[IP_ADDRESS]:9890
Let's Encrypt
Public
Online
book.lakylak.xyz
Created: 31st October 2025
http://[IP_ADDRESS]:6060
Let's Encrypt
Public
Online
crm.lakylak.xyz
Created: 25th July 2025
http://[IP_ADDRESS]:3353
Let's Encrypt
Public
Online
dawarich.lakylak.xyz
Created: 25th August 2025
http://[IP_ADDRESS]:3000
Let's Encrypt
Public
Online
db.screenpipe.lakylak.xyz
Created: 27th April 2026
http://[IP_ADDRESS]:8767
Let's Encrypt
Public
Online
dsk-uploader.lakylak.xyz
Created: 15th August 2025
http://[IP_ADDRESS]:8502
Let's Encrypt
Public
Online
finance-hub.lakylak.xyz
Created: 8th May 2026
http://[IP_ADDRESS]:5175
Let's Encrypt
Public
Online
gitea.lakylak.xyz
Created: 18th July 2025
http://[IP_ADDRESS]:3052
Let's Encrypt
Public
Online
hydra.lakylak.xyz
Created: 29th March 2026
http://[IP_ADDRESS]:4444
Let's Encrypt
Public
Online
images.lakylak.xyz
Created: 17th June 2025
http://[IP_ADDRESS]:3474
Let's Encrypt
Public
Online
immich.lakylak.xyz
Created: 15th June 2025
http://[IP_ADDRESS]:8212
Let's Encrypt
Public
Online
jellyfin.lakylak.xyz
Created: 15th June 2025
http://[IP_ADDRESS]:8096
Let's Encrypt
Public
Online
lakylak.xyz
Created: 15th June 2025
http://[IP_ADDRESS]:9999
Let's Encrypt
Public
Online
linkwarden.lakylak.xyz
Created: 13th December 2025
http://[IP_ADDRESS]:7461
Let's Encrypt
Public
Online
location-tracker.lakylak.xyz
Created: 30th August 2025
http://[IP_ADDRESS]:8050
Let's Encrypt
Public
Online
log.lakylak.xyz
Created: 23rd September 2025
http://[IP_ADDRESS]:18084
Let's Encrypt
Public
Online
login.lakylak.xyz
Created: 29th March 2026
http://[IP_ADDRESS]:4446
Let's Encrypt
Public
Online
mcp.location.lakylak.xyz
Created: 15th March 2026
http://[IP_ADDRESS]:8052
Let's Encrypt
Public
Online
n8n.lakylak.xyz
Created: 17th July 2025
http://[IP_ADDRESS]:5678
Let's Encrypt
Public
Online
nas.lakylak.xyz
Created: 28th July 2025
http://[IP_ADDRESS]:9999
Let's Encrypt
Public
Online
notes.lakylak.xyz
Created: 31st October 2025
http://[IP_ADDRESS]:8085
Let's Encrypt
Public
Online
obsidian.lakylak.xyz
Created: 17th June 2025
http://[IP_ADDRESS]:3421
Let's Encrypt
Public
Online
outfit.lakylak.xyz
Created: 25th March 2026
http://[IP_ADDRESS]:8667
Let's Encrypt
Public
Online
owntracks.lakylak.xyz
Created: 12th August 2025
http://[IP_ADDRESS]:8083
Let's Encrypt
Public
Online
paperless.lakylak.xyz
Created: 25th October 2025
http://[IP_ADDRESS]:8777
Let's Encrypt
Public
Online
payments.lakylak.xyz
Created: 14th February 2026
http://[IP_ADDRESS]:3010
Let's Encrypt
Public
Online
pdf.lakylak.xyz
Created: 19th June 2025
http://[IP_ADDRESS]:7890
Let's Encrypt
Public
Online
portainer.lakylak.xyz
Created: 15th June 2025
http://[IP_ADDRESS]:9000
Let's Encrypt
Public
Online
sqlite.screenpipe.lakylak.xyz
Created: 27th April 2026
http://[IP_ADDRESS]:8768
Let's Encrypt
Public
Online
todo.lakylak.xyz
Created: 16th March 2026
http://reminder-app:8000
Let's Encrypt
Public
Online
tree.lakylak.xyz
Created: 19th December 2025
http://[IP_ADDRESS]:8200
Let's Encrypt
Public
Online
trilium.lakylak.xyz
Created: 24th December 2025
http://[IP_ADDRESS]:4292
Let's Encrypt
Public
Online
tube.lakylak.xyz
Created: 3rd December 2025
http://[IP_ADDRESS]:8770...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
14178
|
629
|
36
|
2026-05-09T17:03:01.173095+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778346181173_m1.jpg...
|
Firefox
|
Nginx Proxy Manager — Personal
|
True
|
http://192.168.0.242:81/nginx/proxy
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Pull requests · screenpipe/screenpipe · GitHub
Clo Pull requests · screenpipe/screenpipe · GitHub
Close tab
DNS / Nameservers | Hostinger
Close tab
Nginx Proxy Manager
Close tab
Screenpipe — Archive
Close tab
SQLite Web: archive.db
Close tab
SQLite Web: db.sqlite
Close tab
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
Close tab
DXP4800PLUS-B5F8
Close tab
AFFiNE - All In One KnowledgeOS
Close tab
All docs · AFFiNE
Close tab
Payments Logger
Close tab
Your old PC can run Windows 11 in a VM, but not on bare metal - [EMAIL] - Gmail
Close tab
Location Logger
Close tab
Finance Hub
Close tab
Finance Hub
Close tab
Select: transactions - db - Adminer
Close tab
Claude Code | Claude Platform
Close tab
Claude
Close tab
lakylak/finance-hub - finance-hub - Gitea: Git with a cup of tea
Close tab
Applications - Admin - authentik
Close tab
New Tab
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Customize sidebar
Nginx Proxy Manager
Nginx Proxy Manager
Admin Administrator
Admin
Administrator
Dashboard
Dashboard
Hosts
Hosts
Access Lists
Access Lists
SSL Certificates
SSL Certificates
Users
Users
Audit Log
Audit Log
Settings
Settings
Proxy Hosts
Proxy Hosts
Search Host…
Add Proxy Host
Add Proxy Host
SOURCE
DESTINATION
SSL
ACCESS
STATUS
ai.chat.lakylak.xyz
Created: 10th March 2026
http://[IP_ADDRESS]:11000
Let's Encrypt
Public
Online
app.lakylak.xyz
Created: 19th July 2025
http://[IP_ADDRESS]:18083
Let's Encrypt
Public
Online
app.payments.lakylak.xyz
Created: 14th February 2026
http://[IP_ADDRESS]:5174
Let's Encrypt
Public
Online
app.screenpipe.lakylak.xyz
Created: 27th April 2026
http://[IP_ADDRESS]:8766
Let's Encrypt
Public
Online
audiobook.lakylak.xyz
Created: 15th June 2025
http://192.168..242:13378
Let's Encrypt
Public
Online
auth.lakylak.xyz
Created: 30th March 2026
http://[IP_ADDRESS]:9100
Let's Encrypt
Public
Online
backup.lakylak.xyz
Created: 10th July 2025
http://[IP_ADDRESS]:9999
Let's Encrypt
Public
Online
beszel.lakylak.xyz
Created: 6th December 2025
http://[IP_ADDRESS]:8095
Let's Encrypt
Public
Online
bitwarden.lakylak.xyz
Created: 16th June 2025
http://[IP_ADDRESS]:9890
Let's Encrypt
Public
Online
book.lakylak.xyz
Created: 31st October 2025
http://[IP_ADDRESS]:6060
Let's Encrypt
Public
Online
crm.lakylak.xyz
Created: 25th July 2025
http://[IP_ADDRESS]:3353
Let's Encrypt
Public
Online
dawarich.lakylak.xyz
Created: 25th August 2025
http://[IP_ADDRESS]:3000
Let's Encrypt
Public
Online
db.screenpipe.lakylak.xyz
Created: 27th April 2026
http://[IP_ADDRESS]:8767
Let's Encrypt
Public
Online
dsk-uploader.lakylak.xyz
Created: 15th August 2025
http://[IP_ADDRESS]:8502
Let's Encrypt
Public
Online
finance-hub.lakylak.xyz
Created: 8th May 2026
http://[IP_ADDRESS]:5175
Let's Encrypt
Public
Online
gitea.lakylak.xyz
Created: 18th July 2025
http://[IP_ADDRESS]:3052
Let's Encrypt
Public
Online
hydra.lakylak.xyz
Created: 29th March 2026
http://[IP_ADDRESS]:4444
Let's Encrypt
Public
Online
images.lakylak.xyz
Created: 17th June 2025
http://[IP_ADDRESS]:3474
Let's Encrypt
Public
Online
immich.lakylak.xyz
Created: 15th June 2025
http://[IP_ADDRESS]:8212
Let's Encrypt
Public
Online
jellyfin.lakylak.xyz
Created: 15th June 2025
http://[IP_ADDRESS]:8096
Let's Encrypt
Public
Online
lakylak.xyz
Created: 15th June 2025
http://[IP_ADDRESS]:9999
Let's Encrypt
Public
Online
linkwarden.lakylak.xyz
Created: 13th December 2025
http://[IP_ADDRESS]:7461
Let's Encrypt
Public
Online
location-tracker.lakylak.xyz
Created: 30th August 2025
http://[IP_ADDRESS]:8050
Let's Encrypt
Public
Online
log.lakylak.xyz
Created: 23rd September 2025
http://[IP_ADDRESS]:18084
Let's Encrypt
Public
Online
login.lakylak.xyz
Created: 29th March 2026
http://[IP_ADDRESS]:4446
Let's Encrypt
Public
Online
mcp.location.lakylak.xyz
Created: 15th March 2026
http://[IP_ADDRESS]:8052
Let's Encrypt
Public
Online
n8n.lakylak.xyz
Created: 17th July 2025
http://[IP_ADDRESS]:5678
Let's Encrypt
Public
Online
nas.lakylak.xyz
Created: 28th July 2025
http://[IP_ADDRESS]:9999
Let's Encrypt
Public
Online
notes.lakylak.xyz
Created: 31st October 2025
http://[IP_ADDRESS]:8085
Let's Encrypt
Public
Online
obsidian.lakylak.xyz
Created: 17th June 2025
http://[IP_ADDRESS]:3421
Let's Encrypt
Public
Online
outfit.lakylak.xyz
Created: 25th March 2026
http://[IP_ADDRESS]:8667
Let's Encrypt
Public
Online
owntracks.lakylak.xyz
Created: 12th August 2025
http://[IP_ADDRESS]:8083
Let's Encrypt
Public
Online
paperless.lakylak.xyz
Created: 25th October 2025
http://[IP_ADDRESS]:8777
Let's Encrypt
Public
Online
payments.lakylak.xyz
Created: 14th February 2026
http://[IP_ADDRESS]:3010
Let's Encrypt
Public
Online
pdf.lakylak.xyz
Created: 19th June 2025
http://[IP_ADDRESS]:7890
Let's Encrypt
Public
Online
portainer.lakylak.xyz
Created: 15th June 2025
http://[IP_ADDRESS]:9000
Let's Encrypt
Public
Online
sqlite.screenpipe.lakylak.xyz
Created: 27th April 2026
http://[IP_ADDRESS]:8768
Let's Encrypt
Public
Online
todo.lakylak.xyz
Created: 16th March 2026
http://reminder-app:8000
Let's Encrypt
Public
Online
tree.lakylak.xyz
Created: 19th December 2025
http://[IP_ADDRESS]:8200
Let's Encrypt
Public
Online
trilium.lakylak.xyz
Created: 24th December 2025
http://[IP_ADDRESS]:4292
Let's Encrypt
Public
Online
tube.lakylak.xyz
Created: 3rd December 2025
http://[IP_ADDRESS]:8770...
|
[{"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":"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":"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":"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":"Nginx Proxy Manager","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"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":"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":"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":"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":"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":"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":"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":"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":"DXP4800PLUS-B5F8","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"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":"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":"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":"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":"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":"Payments Logger","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"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":"Your old PC can run Windows 11 in a VM, but not on bare metal - 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":"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":"Location Logger","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"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":"Finance Hub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"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":"Finance Hub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"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":"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":"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":"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":"Claude","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"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":"lakylak/finance-hub - finance-hub - Gitea: Git with a cup of tea","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"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":"Applications - Admin - authentik","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"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":"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":"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":"AXLink","text":"Nginx Proxy Manager","depth":8,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Nginx Proxy Manager","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Admin Administrator","depth":8,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Admin","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Administrator","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":" Dashboard","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dashboard","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":" Hosts","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hosts","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":" Access Lists","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Access Lists","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":" SSL Certificates","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SSL Certificates","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":" Users","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Users","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":" Audit Log","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Audit Log","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":" 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":"","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":"AXHeading","text":"Proxy Hosts","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Proxy Hosts","depth":10,"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":"AXTextField","text":"Search Host…","depth":10,"on_screen":true,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add Proxy Host","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add Proxy Host","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SOURCE","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DESTINATION","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SSL","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACCESS","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"STATUS","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ai.chat.lakylak.xyz","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 10th March 2026","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:11000","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.lakylak.xyz","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 19th July 2025","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:18083","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.payments.lakylak.xyz","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 14th February 2026","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:5174","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.screenpipe.lakylak.xyz","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 27th April 2026","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8766","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"audiobook.lakylak.xyz","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 15th June 2025","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168..242:13378","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"auth.lakylak.xyz","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 30th March 2026","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:9100","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"backup.lakylak.xyz","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 10th July 2025","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.243:9999","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"beszel.lakylak.xyz","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 6th December 2025","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8095","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"bitwarden.lakylak.xyz","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 16th June 2025","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:9890","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"book.lakylak.xyz","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 31st October 2025","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:6060","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crm.lakylak.xyz","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 25th July 2025","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:3353","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dawarich.lakylak.xyz","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 25th August 2025","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:3000","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"db.screenpipe.lakylak.xyz","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 27th April 2026","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8767","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.1125,"top":0.0,"width":0.05625,"height":0.021666666},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.22951388,"top":0.0,"width":0.027430555,"height":0.021666666},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.31666666,"top":0.0,"width":0.030902777,"height":0.021666666},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.42048612,"top":0.0,"width":0.010416667,"height":0.021666666},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.42048612,"top":0.0,"width":0.010416667,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dsk-uploader.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 15th August 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8502","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.1125,"top":0.05888889,"width":0.05625,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.22951388,"top":0.05888889,"width":0.027430555,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.31666666,"top":0.05888889,"width":0.030902777,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.42048612,"top":0.05888889,"width":0.010416667,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.42048612,"top":0.060555555,"width":0.010416667,"height":0.017222222},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"finance-hub.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 8th May 2026","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:5175","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.1125,"top":0.14166667,"width":0.05625,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.22951388,"top":0.14166667,"width":0.027430555,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.31666666,"top":0.14166667,"width":0.030902777,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.42048612,"top":0.14166667,"width":0.010416667,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.42048612,"top":0.14333333,"width":0.010416667,"height":0.017222222},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"gitea.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 18th July 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:3052","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.1125,"top":0.225,"width":0.05625,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.22951388,"top":0.225,"width":0.027430555,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.31666666,"top":0.225,"width":0.030902777,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.42048612,"top":0.225,"width":0.010416667,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.42048612,"top":0.22666667,"width":0.010416667,"height":0.017222222},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"hydra.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 29th March 2026","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:4444","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.1125,"top":0.3077778,"width":0.05625,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.22951388,"top":0.3077778,"width":0.027430555,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.31666666,"top":0.3077778,"width":0.030902777,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.42048612,"top":0.3077778,"width":0.010416667,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.42048612,"top":0.30944446,"width":0.010416667,"height":0.017222222},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"images.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 17th June 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:3474","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.1125,"top":0.39055556,"width":0.05625,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.22951388,"top":0.39055556,"width":0.027430555,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.31666666,"top":0.39055556,"width":0.030902777,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.42048612,"top":0.39055556,"width":0.010416667,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.42048612,"top":0.39222223,"width":0.010416667,"height":0.017222222},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"immich.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 15th June 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8212","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.1125,"top":0.47388887,"width":0.05625,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.22951388,"top":0.47388887,"width":0.027430555,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.31666666,"top":0.47388887,"width":0.030902777,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.42048612,"top":0.47388887,"width":0.010416667,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.42048612,"top":0.47555557,"width":0.010416667,"height":0.017222222},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jellyfin.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 15th June 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8096","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.1125,"top":0.5566667,"width":0.05625,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.22951388,"top":0.5566667,"width":0.027430555,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.31666666,"top":0.5566667,"width":0.030902777,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.42048612,"top":0.5566667,"width":0.010416667,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.42048612,"top":0.55833334,"width":0.010416667,"height":0.017222222},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 15th June 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:9999","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.1125,"top":0.64,"width":0.05625,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.22951388,"top":0.64,"width":0.027430555,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.31666666,"top":0.64,"width":0.030902777,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.42048612,"top":0.64,"width":0.010416667,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.42048612,"top":0.64166665,"width":0.010416667,"height":0.017222222},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"linkwarden.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 13th December 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:7461","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.1125,"top":0.7227778,"width":0.05625,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.22951388,"top":0.7227778,"width":0.027430555,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.31666666,"top":0.7227778,"width":0.030902777,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.42048612,"top":0.7227778,"width":0.010416667,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.42048612,"top":0.72444445,"width":0.010416667,"height":0.017222222},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"location-tracker.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 30th August 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8050","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.1125,"top":0.8055556,"width":0.05625,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.22951388,"top":0.8055556,"width":0.027430555,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.31666666,"top":0.8055556,"width":0.030902777,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.42048612,"top":0.8055556,"width":0.010416667,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.42048612,"top":0.80722225,"width":0.010416667,"height":0.017222222},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"log.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 23rd September 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:18084","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.1125,"top":0.8888889,"width":0.05625,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.22951388,"top":0.8888889,"width":0.027430555,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.31666666,"top":0.8888889,"width":0.030902777,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.42048612,"top":0.8888889,"width":0.010416667,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.42048612,"top":0.89055556,"width":0.010416667,"height":0.017222222},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"login.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 29th March 2026","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:4446","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.1125,"top":0.9716667,"width":0.05625,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.22951388,"top":0.9716667,"width":0.027430555,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.31666666,"top":0.9716667,"width":0.030902777,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.42048612,"top":0.9716667,"width":0.010416667,"height":0.021666666},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.42048612,"top":0.97333336,"width":0.010416667,"height":0.017222222},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"mcp.location.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 15th March 2026","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8052","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"bounds":{"left":0.1125,"top":1.0,"width":0.05625,"height":-0.054444432},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"bounds":{"left":0.22951388,"top":1.0,"width":0.027430555,"height":-0.054444432},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"bounds":{"left":0.31666666,"top":1.0,"width":0.030902777,"height":-0.054444432},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"bounds":{"left":0.42048612,"top":1.0,"width":0.010416667,"height":-0.054444432},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"bounds":{"left":0.42048612,"top":1.0,"width":0.010416667,"height":-0.056111097},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"n8n.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 17th July 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:5678","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"nas.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 28th July 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:9999","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"notes.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 31st October 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8085","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"obsidian.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 17th June 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:3421","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"outfit.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 25th March 2026","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8667","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"owntracks.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 12th August 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8083","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"paperless.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 25th October 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8777","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"payments.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 14th February 2026","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:3010","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"pdf.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 19th June 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:7890","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"portainer.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 15th June 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:9000","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"sqlite.screenpipe.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 27th April 2026","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8768","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"todo.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 16th March 2026","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://reminder-app:8000","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"tree.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 19th December 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8200","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"trilium.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 24th December 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:4292","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Let's Encrypt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Online","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"tube.lakylak.xyz","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Created: 3rd December 2025","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://192.168.0.242:8770","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8248863909361935441
|
-4931691133008957121
|
click
|
accessibility
|
NULL
|
Pull requests · screenpipe/screenpipe · GitHub
Clo Pull requests · screenpipe/screenpipe · GitHub
Close tab
DNS / Nameservers | Hostinger
Close tab
Nginx Proxy Manager
Close tab
Screenpipe — Archive
Close tab
SQLite Web: archive.db
Close tab
SQLite Web: db.sqlite
Close tab
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
Close tab
DXP4800PLUS-B5F8
Close tab
AFFiNE - All In One KnowledgeOS
Close tab
All docs · AFFiNE
Close tab
Payments Logger
Close tab
Your old PC can run Windows 11 in a VM, but not on bare metal - [EMAIL] - Gmail
Close tab
Location Logger
Close tab
Finance Hub
Close tab
Finance Hub
Close tab
Select: transactions - db - Adminer
Close tab
Claude Code | Claude Platform
Close tab
Claude
Close tab
lakylak/finance-hub - finance-hub - Gitea: Git with a cup of tea
Close tab
Applications - Admin - authentik
Close tab
New Tab
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Customize sidebar
Nginx Proxy Manager
Nginx Proxy Manager
Admin Administrator
Admin
Administrator
Dashboard
Dashboard
Hosts
Hosts
Access Lists
Access Lists
SSL Certificates
SSL Certificates
Users
Users
Audit Log
Audit Log
Settings
Settings
Proxy Hosts
Proxy Hosts
Search Host…
Add Proxy Host
Add Proxy Host
SOURCE
DESTINATION
SSL
ACCESS
STATUS
ai.chat.lakylak.xyz
Created: 10th March 2026
http://[IP_ADDRESS]:11000
Let's Encrypt
Public
Online
app.lakylak.xyz
Created: 19th July 2025
http://[IP_ADDRESS]:18083
Let's Encrypt
Public
Online
app.payments.lakylak.xyz
Created: 14th February 2026
http://[IP_ADDRESS]:5174
Let's Encrypt
Public
Online
app.screenpipe.lakylak.xyz
Created: 27th April 2026
http://[IP_ADDRESS]:8766
Let's Encrypt
Public
Online
audiobook.lakylak.xyz
Created: 15th June 2025
http://192.168..242:13378
Let's Encrypt
Public
Online
auth.lakylak.xyz
Created: 30th March 2026
http://[IP_ADDRESS]:9100
Let's Encrypt
Public
Online
backup.lakylak.xyz
Created: 10th July 2025
http://[IP_ADDRESS]:9999
Let's Encrypt
Public
Online
beszel.lakylak.xyz
Created: 6th December 2025
http://[IP_ADDRESS]:8095
Let's Encrypt
Public
Online
bitwarden.lakylak.xyz
Created: 16th June 2025
http://[IP_ADDRESS]:9890
Let's Encrypt
Public
Online
book.lakylak.xyz
Created: 31st October 2025
http://[IP_ADDRESS]:6060
Let's Encrypt
Public
Online
crm.lakylak.xyz
Created: 25th July 2025
http://[IP_ADDRESS]:3353
Let's Encrypt
Public
Online
dawarich.lakylak.xyz
Created: 25th August 2025
http://[IP_ADDRESS]:3000
Let's Encrypt
Public
Online
db.screenpipe.lakylak.xyz
Created: 27th April 2026
http://[IP_ADDRESS]:8767
Let's Encrypt
Public
Online
dsk-uploader.lakylak.xyz
Created: 15th August 2025
http://[IP_ADDRESS]:8502
Let's Encrypt
Public
Online
finance-hub.lakylak.xyz
Created: 8th May 2026
http://[IP_ADDRESS]:5175
Let's Encrypt
Public
Online
gitea.lakylak.xyz
Created: 18th July 2025
http://[IP_ADDRESS]:3052
Let's Encrypt
Public
Online
hydra.lakylak.xyz
Created: 29th March 2026
http://[IP_ADDRESS]:4444
Let's Encrypt
Public
Online
images.lakylak.xyz
Created: 17th June 2025
http://[IP_ADDRESS]:3474
Let's Encrypt
Public
Online
immich.lakylak.xyz
Created: 15th June 2025
http://[IP_ADDRESS]:8212
Let's Encrypt
Public
Online
jellyfin.lakylak.xyz
Created: 15th June 2025
http://[IP_ADDRESS]:8096
Let's Encrypt
Public
Online
lakylak.xyz
Created: 15th June 2025
http://[IP_ADDRESS]:9999
Let's Encrypt
Public
Online
linkwarden.lakylak.xyz
Created: 13th December 2025
http://[IP_ADDRESS]:7461
Let's Encrypt
Public
Online
location-tracker.lakylak.xyz
Created: 30th August 2025
http://[IP_ADDRESS]:8050
Let's Encrypt
Public
Online
log.lakylak.xyz
Created: 23rd September 2025
http://[IP_ADDRESS]:18084
Let's Encrypt
Public
Online
login.lakylak.xyz
Created: 29th March 2026
http://[IP_ADDRESS]:4446
Let's Encrypt
Public
Online
mcp.location.lakylak.xyz
Created: 15th March 2026
http://[IP_ADDRESS]:8052
Let's Encrypt
Public
Online
n8n.lakylak.xyz
Created: 17th July 2025
http://[IP_ADDRESS]:5678
Let's Encrypt
Public
Online
nas.lakylak.xyz
Created: 28th July 2025
http://[IP_ADDRESS]:9999
Let's Encrypt
Public
Online
notes.lakylak.xyz
Created: 31st October 2025
http://[IP_ADDRESS]:8085
Let's Encrypt
Public
Online
obsidian.lakylak.xyz
Created: 17th June 2025
http://[IP_ADDRESS]:3421
Let's Encrypt
Public
Online
outfit.lakylak.xyz
Created: 25th March 2026
http://[IP_ADDRESS]:8667
Let's Encrypt
Public
Online
owntracks.lakylak.xyz
Created: 12th August 2025
http://[IP_ADDRESS]:8083
Let's Encrypt
Public
Online
paperless.lakylak.xyz
Created: 25th October 2025
http://[IP_ADDRESS]:8777
Let's Encrypt
Public
Online
payments.lakylak.xyz
Created: 14th February 2026
http://[IP_ADDRESS]:3010
Let's Encrypt
Public
Online
pdf.lakylak.xyz
Created: 19th June 2025
http://[IP_ADDRESS]:7890
Let's Encrypt
Public
Online
portainer.lakylak.xyz
Created: 15th June 2025
http://[IP_ADDRESS]:9000
Let's Encrypt
Public
Online
sqlite.screenpipe.lakylak.xyz
Created: 27th April 2026
http://[IP_ADDRESS]:8768
Let's Encrypt
Public
Online
todo.lakylak.xyz
Created: 16th March 2026
http://reminder-app:8000
Let's Encrypt
Public
Online
tree.lakylak.xyz
Created: 19th December 2025
http://[IP_ADDRESS]:8200
Let's Encrypt
Public
Online
trilium.lakylak.xyz
Created: 24th December 2025
http://[IP_ADDRESS]:4292
Let's Encrypt
Public
Online
tube.lakylak.xyz
Created: 3rd December 2025
http://[IP_ADDRESS]:8770...
|
14177
|
NULL
|
NULL
|
NULL
|
|
18961
|
813
|
26
|
2026-05-11T12:04:58.373721+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778501098373_m2.jpg...
|
Code
|
Review rate limit handli… — app
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧ Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧G) - 22 pending changes
22
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update
2
Testing
Claude Code
EXPLORER
EXPLORER
Explorer Section: app
Explorer Section: app
APP
AjReports
Audio
AutomatedReports
Calendar
Crm
Delete
Hubspot
Traits
FetchMergedObjectsPageJob.php
HubspotAppUninstallJob.php
ImportAccountBatch.php
ImportBatchJobTrait.php
ImportContactBatch.php
ImportOpportunityBatch.php
ProcessHubspotWebhookEventsTrait.php
ProcessInternalWebhookEventsJob.php
ProcessMergedObjectJob.php
ProcessWebhookEventsJob.php
UpdateDealWebhookSubscriptionJob.php
Salesforce
AutologDelayedToCrm.php
CheckAndRetryRemoteMatch.php
CreateFollowupActivity.php
CreateNotes.php
MatchActivitiesToNewOpportunity.php
MatchActivityCrmData.php
M
NoteObject.php
SaveActivity.php
SaveTranscription.php
SetupLayout.php
SyncActivity.php
SyncFieldMetadata.php
SyncHubspotObjects.php
SyncLeads.php
SyncObjects.php
SyncOpportunitiesJob.php
SyncOpportunity.php
SyncProfileMetadata.php...
|
[{"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) - 22 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":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":"AXStaticText","text":"22","depth":22,"bounds":{"left":0.007978723,"top":0.1452514,"width":0.0039893617,"height":0.008778931},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.007978723,"top":0.14604948,"width":0.0023271276,"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":"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: app","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: app","depth":22,"bounds":{"left":0.022606382,"top":0.07581804,"width":0.0076462766,"height":0.017557861},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"APP","depth":23,"bounds":{"left":0.022606382,"top":0.079010375,"width":0.0076462766,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.0933759,"width":0.005319149,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AjReports","depth":27,"bounds":{"left":0.03125,"top":0.0933759,"width":0.019614361,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.0933759,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":8,"bounds":{"left":0.034242023,"top":0.0933759,"width":0.01662234,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.110135674,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Audio","depth":27,"bounds":{"left":0.03125,"top":0.110135674,"width":0.011635638,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.11093376,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":4,"bounds":{"left":0.034242023,"top":0.11093376,"width":0.008643617,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.12769353,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReports","depth":27,"bounds":{"left":0.03125,"top":0.12769353,"width":0.03756649,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.12849163,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":15,"bounds":{"left":0.034242023,"top":0.12849163,"width":0.034906916,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.1452514,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Calendar","depth":27,"bounds":{"left":0.03125,"top":0.1452514,"width":0.017952127,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.14604948,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":7,"bounds":{"left":0.034242023,"top":0.14604948,"width":0.015292553,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.16280925,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":27,"bounds":{"left":0.03125,"top":0.16280925,"width":0.00831117,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.10605053,"top":0.16360734,"width":0.004654255,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.027593086,"top":0.18036711,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Delete","depth":27,"bounds":{"left":0.033909574,"top":0.18036711,"width":0.012965426,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.1811652,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":5,"bounds":{"left":0.03723404,"top":0.1811652,"width":0.009640957,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.027593086,"top":0.19792499,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":27,"bounds":{"left":0.033909574,"top":0.19792499,"width":0.017287234,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.19872306,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":6,"bounds":{"left":0.03723404,"top":0.19872306,"width":0.013962766,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.03025266,"top":0.21548285,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":27,"bounds":{"left":0.03656915,"top":0.21548285,"width":0.011303191,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.21628092,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":5,"bounds":{"left":0.038896278,"top":0.21628092,"width":0.008976064,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.23144454,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"FetchMergedObjectsPageJob.php","depth":27,"bounds":{"left":0.03656915,"top":0.2330407,"width":0.06881649,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.23383878,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":28,"bounds":{"left":0.039228722,"top":0.23383878,"width":0.06615692,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.2490024,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HubspotAppUninstallJob.php","depth":27,"bounds":{"left":0.03656915,"top":0.25059855,"width":0.059175532,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.25139666,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":25,"bounds":{"left":0.039893616,"top":0.25139666,"width":0.055851065,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.26656026,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ImportAccountBatch.php","depth":27,"bounds":{"left":0.03656915,"top":0.26815644,"width":0.050531916,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.26895452,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":21,"bounds":{"left":0.037898935,"top":0.26895452,"width":0.04920213,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.28411812,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ImportBatchJobTrait.php","depth":27,"bounds":{"left":0.03656915,"top":0.2857143,"width":0.049867023,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.28651237,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":22,"bounds":{"left":0.037898935,"top":0.28651237,"width":0.048537236,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.30167598,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ImportContactBatch.php","depth":27,"bounds":{"left":0.03656915,"top":0.30327216,"width":0.049867023,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.30407023,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":21,"bounds":{"left":0.037898935,"top":0.30407023,"width":0.048537236,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.31923383,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ImportOpportunityBatch.php","depth":27,"bounds":{"left":0.03656915,"top":0.32083002,"width":0.057845745,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.3216281,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":25,"bounds":{"left":0.037898935,"top":0.3216281,"width":0.056848403,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.3367917,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotWebhookEventsTrait.php","depth":27,"bounds":{"left":0.03656915,"top":0.33838788,"width":0.077792555,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.33918595,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":35,"bounds":{"left":0.039228722,"top":0.33918595,"width":0.080784574,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.35434955,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ProcessInternalWebhookEventsJob.php","depth":27,"bounds":{"left":0.03656915,"top":0.35594574,"width":0.078457445,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.3567438,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":34,"bounds":{"left":0.039228722,"top":0.3567438,"width":0.0774601,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.3719074,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ProcessMergedObjectJob.php","depth":27,"bounds":{"left":0.03656915,"top":0.3735036,"width":0.061170213,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.37430167,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":25,"bounds":{"left":0.039228722,"top":0.37430167,"width":0.058843084,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.38946527,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ProcessWebhookEventsJob.php","depth":27,"bounds":{"left":0.03656915,"top":0.39106146,"width":0.06482713,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.39185953,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":26,"bounds":{"left":0.039228722,"top":0.39185953,"width":0.06216755,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.40702313,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"UpdateDealWebhookSubscriptionJob.php","depth":27,"bounds":{"left":0.03656915,"top":0.4086193,"width":0.076130316,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.4094174,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":35,"bounds":{"left":0.039893616,"top":0.4094174,"width":0.08111702,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.027593086,"top":0.42617717,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Salesforce","depth":27,"bounds":{"left":0.033909574,"top":0.42617717,"width":0.021276595,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.42697525,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":9,"bounds":{"left":0.03656915,"top":0.42697525,"width":0.01861702,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.44213888,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedToCrm.php","depth":27,"bounds":{"left":0.033909574,"top":0.44373503,"width":0.053856384,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.4445331,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":22,"bounds":{"left":0.036901597,"top":0.4445331,"width":0.05119681,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.45969674,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"CheckAndRetryRemoteMatch.php","depth":27,"bounds":{"left":0.033909574,"top":0.4612929,"width":0.068484046,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.46209097,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":27,"bounds":{"left":0.036901597,"top":0.46209097,"width":0.06549202,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.4772546,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"CreateFollowupActivity.php","depth":27,"bounds":{"left":0.033909574,"top":0.47885075,"width":0.054853722,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.47964883,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":25,"bounds":{"left":0.036901597,"top":0.47964883,"width":0.051861703,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.49481246,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"CreateNotes.php","depth":27,"bounds":{"left":0.033909574,"top":0.4964086,"width":0.034242023,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.49720672,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":14,"bounds":{"left":0.036901597,"top":0.49720672,"width":0.03125,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.5123703,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchActivitiesToNewOpportunity.php","depth":27,"bounds":{"left":0.033909574,"top":0.5139665,"width":0.07712766,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.51476455,"width":0.0039893617,"height":0.011971269}},{"char_start":1,"char_count":34,"bounds":{"left":0.037898935,"top":0.51476455,"width":0.07347074,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.52992815,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchActivityCrmData.php","depth":27,"bounds":{"left":0.033909574,"top":0.53152436,"width":0.054521278,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.5323224,"width":0.0039893617,"height":0.011971269}},{"char_start":1,"char_count":23,"bounds":{"left":0.037898935,"top":0.5323224,"width":0.050531916,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":27,"bounds":{"left":0.10638298,"top":0.5323224,"width":0.003656915,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.547486,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"NoteObject.php","depth":27,"bounds":{"left":0.033909574,"top":0.5490822,"width":0.031914894,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.54988027,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":13,"bounds":{"left":0.03723404,"top":0.54988027,"width":0.028922873,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.56504387,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SaveActivity.php","depth":27,"bounds":{"left":0.033909574,"top":0.5666401,"width":0.03324468,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.5674381,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":15,"bounds":{"left":0.03656915,"top":0.5674381,"width":0.030585106,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.5826017,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SaveTranscription.php","depth":27,"bounds":{"left":0.033909574,"top":0.58419794,"width":0.04454787,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.584996,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":20,"bounds":{"left":0.03656915,"top":0.584996,"width":0.042220745,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.60015965,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayout.php","depth":27,"bounds":{"left":0.033909574,"top":0.6017558,"width":0.034242023,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.60255384,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":14,"bounds":{"left":0.03656915,"top":0.60255384,"width":0.031914894,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.6177175,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncActivity.php","depth":27,"bounds":{"left":0.033909574,"top":0.61931366,"width":0.03357713,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.6201117,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":15,"bounds":{"left":0.03656915,"top":0.6201117,"width":0.030917553,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.63527536,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php","depth":27,"bounds":{"left":0.033909574,"top":0.6368715,"width":0.047539894,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.63766956,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":20,"bounds":{"left":0.03656915,"top":0.63766956,"width":0.04488032,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.6528332,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php","depth":27,"bounds":{"left":0.033909574,"top":0.6544294,"width":0.051861703,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.6552275,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":21,"bounds":{"left":0.03656915,"top":0.6552275,"width":0.04920213,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.6703911,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncLeads.php","depth":27,"bounds":{"left":0.033909574,"top":0.67198724,"width":0.030917553,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.67278534,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":12,"bounds":{"left":0.03656915,"top":0.67278534,"width":0.02825798,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.68794894,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php","depth":27,"bounds":{"left":0.033909574,"top":0.6895451,"width":0.034574468,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.6903432,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":14,"bounds":{"left":0.03656915,"top":0.6903432,"width":0.031914894,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.7055068,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesJob.php","depth":27,"bounds":{"left":0.033909574,"top":0.70710295,"width":0.053856384,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.70790106,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":23,"bounds":{"left":0.03656915,"top":0.70790106,"width":0.05119681,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.72306466,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php","depth":27,"bounds":{"left":0.033909574,"top":0.7246608,"width":0.04288564,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.7254589,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":18,"bounds":{"left":0.03656915,"top":0.7254589,"width":0.040226065,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.7406225,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php","depth":27,"bounds":{"left":0.033909574,"top":0.7422187,"width":0.05086436,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.7430168,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":22,"bounds":{"left":0.03656915,"top":0.7430168,"width":0.048204787,"height":0.011971269}}],"role_description":"text"}]...
|
-8246760609947367837
|
8896883523960643914
|
visual_change
|
accessibility
|
NULL
|
Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧ Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧G) - 22 pending changes
22
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update
2
Testing
Claude Code
EXPLORER
EXPLORER
Explorer Section: app
Explorer Section: app
APP
AjReports
Audio
AutomatedReports
Calendar
Crm
Delete
Hubspot
Traits
FetchMergedObjectsPageJob.php
HubspotAppUninstallJob.php
ImportAccountBatch.php
ImportBatchJobTrait.php
ImportContactBatch.php
ImportOpportunityBatch.php
ProcessHubspotWebhookEventsTrait.php
ProcessInternalWebhookEventsJob.php
ProcessMergedObjectJob.php
ProcessWebhookEventsJob.php
UpdateDealWebhookSubscriptionJob.php
Salesforce
AutologDelayedToCrm.php
CheckAndRetryRemoteMatch.php
CreateFollowupActivity.php
CreateNotes.php
MatchActivitiesToNewOpportunity.php
MatchActivityCrmData.php
M
NoteObject.php
SaveActivity.php
SaveTranscription.php
SetupLayout.php
SyncActivity.php
SyncFieldMetadata.php
SyncHubspotObjects.php
SyncLeads.php
SyncObjects.php
SyncOpportunitiesJob.php
SyncOpportunity.php
SyncProfileMetadata.php...
|
18959
|
NULL
|
NULL
|
NULL
|
|
18980
|
815
|
8
|
2026-05-11T12:06:18.371201+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778501178371_m2.jpg...
|
Code
|
Review rate limit handli… — app
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧ Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧G) - 22 pending changes
22
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update
2
Testing
Claude Code
EXPLORER
EXPLORER
Explorer Section: app
Explorer Section: app
APP
AjReports
Audio
AutomatedReports
Calendar
Crm
Delete
Hubspot
Traits
FetchMergedObjectsPageJob.php
HubspotAppUninstallJob.php
ImportAccountBatch.php
ImportBatchJobTrait.php
ImportContactBatch.php
ImportOpportunityBatch.php
ProcessHubspotWebhookEventsTrait.php
ProcessInternalWebhookEventsJob.php
ProcessMergedObjectJob.php
ProcessWebhookEventsJob.php
UpdateDealWebhookSubscriptionJob.php
Salesforce
AutologDelayedToCrm.php
CheckAndRetryRemoteMatch.php
CreateFollowupActivity.php
CreateNotes.php
MatchActivitiesToNewOpportunity.php
MatchActivityCrmData.php
M
NoteObject.php
SaveActivity.php
SaveTranscription.php
SetupLayout.php
SyncActivity.php
SyncFieldMetadata.php
SyncHubspotObjects.php
SyncLeads.php
SyncObjects.php
SyncOpportunitiesJob.php
SyncOpportunity.php
SyncProfileMetadata.php...
|
[{"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) - 22 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":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":"AXStaticText","text":"22","depth":22,"bounds":{"left":0.007978723,"top":0.1452514,"width":0.0039893617,"height":0.008778931},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.007978723,"top":0.14604948,"width":0.0023271276,"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":"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: app","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: app","depth":22,"bounds":{"left":0.022606382,"top":0.07581804,"width":0.0076462766,"height":0.017557861},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"APP","depth":23,"bounds":{"left":0.022606382,"top":0.079010375,"width":0.0076462766,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.0933759,"width":0.005319149,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AjReports","depth":27,"bounds":{"left":0.03125,"top":0.0933759,"width":0.019614361,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.0933759,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":8,"bounds":{"left":0.034242023,"top":0.0933759,"width":0.01662234,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.110135674,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Audio","depth":27,"bounds":{"left":0.03125,"top":0.110135674,"width":0.011635638,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.11093376,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":4,"bounds":{"left":0.034242023,"top":0.11093376,"width":0.008643617,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.12769353,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReports","depth":27,"bounds":{"left":0.03125,"top":0.12769353,"width":0.03756649,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.12849163,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":15,"bounds":{"left":0.034242023,"top":0.12849163,"width":0.034906916,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.1452514,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Calendar","depth":27,"bounds":{"left":0.03125,"top":0.1452514,"width":0.017952127,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.14604948,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":7,"bounds":{"left":0.034242023,"top":0.14604948,"width":0.015292553,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.16280925,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":27,"bounds":{"left":0.03125,"top":0.16280925,"width":0.00831117,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.10605053,"top":0.16360734,"width":0.004654255,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.027593086,"top":0.18036711,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Delete","depth":27,"bounds":{"left":0.033909574,"top":0.18036711,"width":0.012965426,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.1811652,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":5,"bounds":{"left":0.03723404,"top":0.1811652,"width":0.009640957,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.027593086,"top":0.19792499,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":27,"bounds":{"left":0.033909574,"top":0.19792499,"width":0.017287234,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.19872306,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":6,"bounds":{"left":0.03723404,"top":0.19872306,"width":0.013962766,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.03025266,"top":0.21548285,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":27,"bounds":{"left":0.03656915,"top":0.21548285,"width":0.011303191,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.21628092,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":5,"bounds":{"left":0.038896278,"top":0.21628092,"width":0.008976064,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.23144454,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"FetchMergedObjectsPageJob.php","depth":27,"bounds":{"left":0.03656915,"top":0.2330407,"width":0.06881649,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.23383878,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":28,"bounds":{"left":0.039228722,"top":0.23383878,"width":0.06615692,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.2490024,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HubspotAppUninstallJob.php","depth":27,"bounds":{"left":0.03656915,"top":0.25059855,"width":0.059175532,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.25139666,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":25,"bounds":{"left":0.039893616,"top":0.25139666,"width":0.055851065,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.26656026,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ImportAccountBatch.php","depth":27,"bounds":{"left":0.03656915,"top":0.26815644,"width":0.050531916,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.26895452,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":21,"bounds":{"left":0.037898935,"top":0.26895452,"width":0.04920213,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.28411812,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ImportBatchJobTrait.php","depth":27,"bounds":{"left":0.03656915,"top":0.2857143,"width":0.049867023,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.28651237,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":22,"bounds":{"left":0.037898935,"top":0.28651237,"width":0.048537236,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.30167598,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ImportContactBatch.php","depth":27,"bounds":{"left":0.03656915,"top":0.30327216,"width":0.049867023,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.30407023,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":21,"bounds":{"left":0.037898935,"top":0.30407023,"width":0.048537236,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.31923383,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ImportOpportunityBatch.php","depth":27,"bounds":{"left":0.03656915,"top":0.32083002,"width":0.057845745,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.3216281,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":25,"bounds":{"left":0.037898935,"top":0.3216281,"width":0.056848403,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.3367917,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotWebhookEventsTrait.php","depth":27,"bounds":{"left":0.03656915,"top":0.33838788,"width":0.077792555,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.33918595,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":35,"bounds":{"left":0.039228722,"top":0.33918595,"width":0.080784574,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.35434955,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ProcessInternalWebhookEventsJob.php","depth":27,"bounds":{"left":0.03656915,"top":0.35594574,"width":0.078457445,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.3567438,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":34,"bounds":{"left":0.039228722,"top":0.3567438,"width":0.0774601,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.3719074,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ProcessMergedObjectJob.php","depth":27,"bounds":{"left":0.03656915,"top":0.3735036,"width":0.061170213,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.37430167,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":25,"bounds":{"left":0.039228722,"top":0.37430167,"width":0.058843084,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.38946527,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ProcessWebhookEventsJob.php","depth":27,"bounds":{"left":0.03656915,"top":0.39106146,"width":0.06482713,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.39185953,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":26,"bounds":{"left":0.039228722,"top":0.39185953,"width":0.06216755,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.02925532,"top":0.40702313,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"UpdateDealWebhookSubscriptionJob.php","depth":27,"bounds":{"left":0.03656915,"top":0.4086193,"width":0.076130316,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03656915,"top":0.4094174,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":35,"bounds":{"left":0.039893616,"top":0.4094174,"width":0.08111702,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.027593086,"top":0.42617717,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Salesforce","depth":27,"bounds":{"left":0.033909574,"top":0.42617717,"width":0.021276595,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.42697525,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":9,"bounds":{"left":0.03656915,"top":0.42697525,"width":0.01861702,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.44213888,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedToCrm.php","depth":27,"bounds":{"left":0.033909574,"top":0.44373503,"width":0.053856384,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.4445331,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":22,"bounds":{"left":0.036901597,"top":0.4445331,"width":0.05119681,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.45969674,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"CheckAndRetryRemoteMatch.php","depth":27,"bounds":{"left":0.033909574,"top":0.4612929,"width":0.068484046,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.46209097,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":27,"bounds":{"left":0.036901597,"top":0.46209097,"width":0.06549202,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.4772546,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"CreateFollowupActivity.php","depth":27,"bounds":{"left":0.033909574,"top":0.47885075,"width":0.054853722,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.47964883,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":25,"bounds":{"left":0.036901597,"top":0.47964883,"width":0.051861703,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.49481246,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"CreateNotes.php","depth":27,"bounds":{"left":0.033909574,"top":0.4964086,"width":0.034242023,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.49720672,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":14,"bounds":{"left":0.036901597,"top":0.49720672,"width":0.03125,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.5123703,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchActivitiesToNewOpportunity.php","depth":27,"bounds":{"left":0.033909574,"top":0.5139665,"width":0.07712766,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.51476455,"width":0.0039893617,"height":0.011971269}},{"char_start":1,"char_count":34,"bounds":{"left":0.037898935,"top":0.51476455,"width":0.07347074,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.52992815,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchActivityCrmData.php","depth":27,"bounds":{"left":0.033909574,"top":0.53152436,"width":0.054521278,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.5323224,"width":0.0039893617,"height":0.011971269}},{"char_start":1,"char_count":23,"bounds":{"left":0.037898935,"top":0.5323224,"width":0.050531916,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":27,"bounds":{"left":0.10638298,"top":0.5323224,"width":0.003656915,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.547486,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"NoteObject.php","depth":27,"bounds":{"left":0.033909574,"top":0.5490822,"width":0.031914894,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.54988027,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":13,"bounds":{"left":0.03723404,"top":0.54988027,"width":0.028922873,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.56504387,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SaveActivity.php","depth":27,"bounds":{"left":0.033909574,"top":0.5666401,"width":0.03324468,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.5674381,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":15,"bounds":{"left":0.03656915,"top":0.5674381,"width":0.030585106,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.5826017,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SaveTranscription.php","depth":27,"bounds":{"left":0.033909574,"top":0.58419794,"width":0.04454787,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.584996,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":20,"bounds":{"left":0.03656915,"top":0.584996,"width":0.042220745,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.60015965,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayout.php","depth":27,"bounds":{"left":0.033909574,"top":0.6017558,"width":0.034242023,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.60255384,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":14,"bounds":{"left":0.03656915,"top":0.60255384,"width":0.031914894,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.6177175,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncActivity.php","depth":27,"bounds":{"left":0.033909574,"top":0.61931366,"width":0.03357713,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.6201117,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":15,"bounds":{"left":0.03656915,"top":0.6201117,"width":0.030917553,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.63527536,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php","depth":27,"bounds":{"left":0.033909574,"top":0.6368715,"width":0.047539894,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.63766956,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":20,"bounds":{"left":0.03656915,"top":0.63766956,"width":0.04488032,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.6528332,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php","depth":27,"bounds":{"left":0.033909574,"top":0.6544294,"width":0.051861703,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.6552275,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":21,"bounds":{"left":0.03656915,"top":0.6552275,"width":0.04920213,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.6703911,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncLeads.php","depth":27,"bounds":{"left":0.033909574,"top":0.67198724,"width":0.030917553,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.67278534,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":12,"bounds":{"left":0.03656915,"top":0.67278534,"width":0.02825798,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.68794894,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php","depth":27,"bounds":{"left":0.033909574,"top":0.6895451,"width":0.034574468,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.6903432,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":14,"bounds":{"left":0.03656915,"top":0.6903432,"width":0.031914894,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.7055068,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesJob.php","depth":27,"bounds":{"left":0.033909574,"top":0.70710295,"width":0.053856384,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.70790106,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":23,"bounds":{"left":0.03656915,"top":0.70790106,"width":0.05119681,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.72306466,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php","depth":27,"bounds":{"left":0.033909574,"top":0.7246608,"width":0.04288564,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.7254589,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":18,"bounds":{"left":0.03656915,"top":0.7254589,"width":0.040226065,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.7406225,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php","depth":27,"bounds":{"left":0.033909574,"top":0.7422187,"width":0.05086436,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.7430168,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":22,"bounds":{"left":0.03656915,"top":0.7430168,"width":0.048204787,"height":0.011971269}}],"role_description":"text"}]...
|
-8246760609947367837
|
8896883523960643914
|
click
|
accessibility
|
NULL
|
Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧ Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧G) - 22 pending changes
22
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update
2
Testing
Claude Code
EXPLORER
EXPLORER
Explorer Section: app
Explorer Section: app
APP
AjReports
Audio
AutomatedReports
Calendar
Crm
Delete
Hubspot
Traits
FetchMergedObjectsPageJob.php
HubspotAppUninstallJob.php
ImportAccountBatch.php
ImportBatchJobTrait.php
ImportContactBatch.php
ImportOpportunityBatch.php
ProcessHubspotWebhookEventsTrait.php
ProcessInternalWebhookEventsJob.php
ProcessMergedObjectJob.php
ProcessWebhookEventsJob.php
UpdateDealWebhookSubscriptionJob.php
Salesforce
AutologDelayedToCrm.php
CheckAndRetryRemoteMatch.php
CreateFollowupActivity.php
CreateNotes.php
MatchActivitiesToNewOpportunity.php
MatchActivityCrmData.php
M
NoteObject.php
SaveActivity.php
SaveTranscription.php
SetupLayout.php
SyncActivity.php
SyncFieldMetadata.php
SyncHubspotObjects.php
SyncLeads.php
SyncObjects.php
SyncOpportunitiesJob.php
SyncOpportunity.php
SyncProfileMetadata.php...
|
18978
|
NULL
|
NULL
|
NULL
|
|
22549
|
972
|
40
|
2026-05-12T07:13:15.177134+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778569995177_m1.jpg...
|
Firefox
|
planhat - Google Search — Work
|
True
|
NULL
|
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
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
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
LLM pricing overview with the most actual prices - Google Search
LLM pricing overview with the most actual prices - Google Search
planhat - Google Search
planhat - Google Search
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)...
|
[{"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":"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 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":false},{"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":"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":"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":"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":"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":"LLM pricing overview with the most actual prices - Google Search","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LLM pricing overview with the most actual prices - Google Search","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"planhat - Google Search","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"planhat - Google Search","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.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":"Close 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.019097222,"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}]...
|
-8243821770060575709
|
-2444025834583934333
|
visual_change
|
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
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
LLM pricing overview with the most actual prices - Google Search
LLM pricing overview with the most actual prices - Google Search
planhat - Google Search
planhat - Google Search
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)...
|
22548
|
NULL
|
NULL
|
NULL
|
|
25948
|
1083
|
16
|
2026-05-12T11:56:00.592041+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778586960592_m2.jpg...
|
Firefox
|
TypeError: League\Flysystem\Filesystem::has(): Arg 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 — Work...
|
True
|
jiminny.sentry.io/issues/6873095751/events/?projec jiminny.sentry.io/issues/6873095751/events/?project=82419&query=&statsPeriod=24h...
|
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
Close tab
CloudWatch | us-east-2
CloudWatch | us-east-2
test (885333) - jiminny/app
test (885333) - 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
Userpilot | Events
Userpilot | Events
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Toggle organization menu
Issues
Issues
Explore
Explore
Dashboards
Dashboards
Monitors
Monitors
Settings
Settings
Try Business
What's New
Help
[EMAIL]
Issues
Expand
Feed
Feed
Errors & Outages
Errors & Outages
Breached Metrics
Breached Metrics
Warnings
Warnings
User Feedback
User Feedback
Autofix
Autofix
Recently Run
Recently Run
All Views
All Views
Configure
Alerts Moved
Alerts
Moved
Issues
Issues
View Project Details
APP-1DTF
Ask Seer
Ask Seer
/
Give Feedback
TypeError
View events
Events (total)
Users (90d)
Level: Error
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
2.4K
0
Ongoing
/app/Jobs/AutomatedReports/SendReportJob.php in Jiminny\Jobs\AutomatedReports\SendReportJob::handle
Quick Fix
Resolve
Resolve
More resolve options
Archive
Archive
Archive options
Subscribe
Share
More Actions
Priority
Modify issue priority
High
Assignee
Modify issue assignee
Nikolay Nikolov
All Envs
All Envs
24H
24H
Add a search term
Add a search term
Close sidebar
Toggle graph series - Events
Events
66
Toggle graph series - Users
Users
0
release 9% 881233
release
9%
881233
environment 73% production
environment
73%
production
runtime.name 100% php
runtime.name
100%
php
os 55% Linux 6.1.164-196.303.amzn2023.aarch64
os
55%
Linux 6.1.164-196.303.amzn2023.aarch64
View all tags
View all tags
Select issue content
Events
Open in Discover
Open in Discover
Return to event details
Close
All Events
Showing
1
-
50
of
66
matching
events
Previous Page
Next Page
Event ID
Timestamp
Timestamp
Title
Title
Transaction
Transaction
Release
Release
Environment
Environment
User
User
Device
Device
OS
OS
URL
URL
Runtime
Runtime...
|
[{"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":true},{"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":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.087789305,"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":"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":"test (885333) - 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":"test (885333) - jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.15762171,"width":0.048038565,"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":"Userpilot | Events","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":false},{"role":"AXStaticText","text":"Userpilot | Events","depth":5,"bounds":{"left":0.013297873,"top":0.4521149,"width":0.030418882,"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.47486034,"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":"AXLink","text":"Skip to main content","depth":8,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to main content","depth":9,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Toggle organization menu","depth":11,"bounds":{"left":0.08643617,"top":0.059856344,"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,"is_expanded":false},{"role":"AXLink","text":"Issues","depth":12,"bounds":{"left":0.0809508,"top":0.09736632,"width":0.021609042,"height":0.050678372},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":14,"bounds":{"left":0.0866024,"top":0.13048683,"width":0.010305851,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore","depth":12,"bounds":{"left":0.0809508,"top":0.14804469,"width":0.021609042,"height":0.050678372},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore","depth":14,"bounds":{"left":0.08577128,"top":0.1811652,"width":0.011968086,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Dashboards","depth":12,"bounds":{"left":0.0809508,"top":0.19872306,"width":0.021609042,"height":0.05027933},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Dashboards","depth":14,"bounds":{"left":0.08211436,"top":0.23184358,"width":0.019281914,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Monitors","depth":12,"bounds":{"left":0.0809508,"top":0.2490024,"width":0.021609042,"height":0.050678372},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Monitors","depth":14,"bounds":{"left":0.084773935,"top":0.2821229,"width":0.013962766,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"bounds":{"left":0.0809508,"top":0.29968077,"width":0.021609042,"height":0.050678372},"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,"bounds":{"left":0.08494016,"top":0.33280128,"width":0.013630319,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Try Business","depth":10,"bounds":{"left":0.08643617,"top":0.88667196,"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":"What's New","depth":10,"bounds":{"left":0.08643617,"top":0.9114126,"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,"is_expanded":false},{"role":"AXButton","text":"Help","depth":10,"bounds":{"left":0.08643617,"top":0.93615323,"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,"is_expanded":false},{"role":"AXButton","text":"lukas.kovalik@jiminny.com","depth":10,"bounds":{"left":0.08643617,"top":0.9680766,"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,"is_expanded":false},{"role":"AXStaticText","text":"Issues","depth":13,"bounds":{"left":0.04305186,"top":0.066640064,"width":0.014461436,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Expand","depth":13,"bounds":{"left":0.088597074,"top":0.061452515,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Feed","depth":15,"bounds":{"left":0.039727394,"top":0.10055866,"width":0.058843084,"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":"Feed","depth":17,"bounds":{"left":0.044049203,"top":0.10734238,"width":0.010638298,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Errors & Outages","depth":15,"bounds":{"left":0.039727394,"top":0.14046289,"width":0.058843084,"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":"Errors & Outages","depth":17,"bounds":{"left":0.044049203,"top":0.14724661,"width":0.03673537,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Breached Metrics","depth":15,"bounds":{"left":0.039727394,"top":0.16759777,"width":0.058843084,"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":"Breached Metrics","depth":17,"bounds":{"left":0.044049203,"top":0.17438148,"width":0.037898935,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Warnings","depth":15,"bounds":{"left":0.039727394,"top":0.19473264,"width":0.058843084,"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":"Warnings","depth":17,"bounds":{"left":0.044049203,"top":0.20151636,"width":0.019946808,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Feedback","depth":15,"bounds":{"left":0.039727394,"top":0.22186752,"width":0.058843084,"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":"User Feedback","depth":17,"bounds":{"left":0.044049203,"top":0.22865124,"width":0.032081116,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Autofix","depth":13,"bounds":{"left":0.039727394,"top":0.26177174,"width":0.058843084,"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":"Autofix","depth":16,"bounds":{"left":0.043716755,"top":0.26855546,"width":0.016289894,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Recently Run","depth":15,"bounds":{"left":0.039727394,"top":0.28731045,"width":0.058843084,"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":"Recently Run","depth":17,"bounds":{"left":0.044049203,"top":0.29409418,"width":0.028922873,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"All Views","depth":15,"bounds":{"left":0.039727394,"top":0.3272147,"width":0.058843084,"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":"All Views","depth":17,"bounds":{"left":0.044049203,"top":0.3339984,"width":0.019281914,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Configure","depth":14,"bounds":{"left":0.043716755,"top":0.3735036,"width":0.021941489,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Alerts Moved","depth":15,"bounds":{"left":0.039727394,"top":0.39225858,"width":0.058843084,"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":"Alerts","depth":17,"bounds":{"left":0.044049203,"top":0.3990423,"width":0.012799202,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Moved","depth":17,"bounds":{"left":0.08045213,"top":0.39984038,"width":0.012466756,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Issues","depth":12,"bounds":{"left":0.10954122,"top":0.06464485,"width":0.013796543,"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":"Issues","depth":14,"bounds":{"left":0.10954122,"top":0.066640064,"width":0.013796543,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"View Project Details","depth":13,"bounds":{"left":0.1299867,"top":0.06624102,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"APP-1DTF","depth":16,"bounds":{"left":0.13796543,"top":0.066640064,"width":0.021609042,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Ask Seer","depth":10,"bounds":{"left":0.93484044,"top":0.059856344,"width":0.04720745,"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 Seer","depth":13,"bounds":{"left":0.9461436,"top":0.0650439,"width":0.019614361,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":14,"bounds":{"left":0.9740692,"top":0.065442935,"width":0.0021609042,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Give Feedback","depth":11,"bounds":{"left":0.9840425,"top":0.059856344,"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":"TypeError","depth":13,"bounds":{"left":0.10954122,"top":0.10295291,"width":0.03174867,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"View events","depth":13,"bounds":{"left":0.9409907,"top":0.10654429,"width":0.026097074,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Events (total)","depth":14,"bounds":{"left":0.9409907,"top":0.10654429,"width":0.026097074,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Users (90d)","depth":13,"bounds":{"left":0.9724069,"top":0.10654429,"width":0.022273935,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Level: Error","depth":15,"bounds":{"left":0.10920878,"top":0.12490024,"width":0.02443484,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"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","depth":14,"bounds":{"left":0.11253324,"top":0.12490024,"width":0.453125,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2.4K","depth":13,"bounds":{"left":0.9534575,"top":0.12210695,"width":0.013630319,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":13,"bounds":{"left":0.99052525,"top":0.12210695,"width":0.004155585,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Ongoing","depth":14,"bounds":{"left":0.10954122,"top":0.14046289,"width":0.018118352,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/app/Jobs/AutomatedReports/SendReportJob.php in Jiminny\\Jobs\\AutomatedReports\\SendReportJob::handle","depth":13,"bounds":{"left":0.13447474,"top":0.14046289,"width":0.24534574,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Quick Fix","depth":14,"bounds":{"left":0.3912899,"top":0.14046289,"width":0.019614361,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Resolve","depth":12,"bounds":{"left":0.10954122,"top":0.16719872,"width":0.02543218,"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":"Resolve","depth":14,"bounds":{"left":0.11353058,"top":0.17238627,"width":0.017453458,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"More resolve options","depth":12,"bounds":{"left":0.13464096,"top":0.16719872,"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,"is_expanded":false},{"role":"AXButton","text":"Archive","depth":12,"bounds":{"left":0.14660904,"top":0.16719872,"width":0.025265958,"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":"Archive","depth":14,"bounds":{"left":0.1505984,"top":0.17238627,"width":0.017287234,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Archive options","depth":12,"bounds":{"left":0.17154256,"top":0.16719872,"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,"is_expanded":false},{"role":"AXButton","text":"Subscribe","depth":12,"bounds":{"left":0.18351063,"top":0.16719872,"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":"Share","depth":12,"bounds":{"left":0.19547872,"top":0.16719872,"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":"More Actions","depth":12,"bounds":{"left":0.20744681,"top":0.16719872,"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,"is_expanded":false},{"role":"AXStaticText","text":"Priority","depth":12,"bounds":{"left":0.89544547,"top":0.17398244,"width":0.015791224,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Modify issue priority","depth":12,"bounds":{"left":0.9125665,"top":0.17039107,"width":0.013962766,"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":"AXStaticText","text":"High","depth":17,"bounds":{"left":0.91954786,"top":0.18076617,"width":0.008976064,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Assignee","depth":12,"bounds":{"left":0.9318484,"top":0.17398244,"width":0.019946808,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Modify issue assignee","depth":13,"bounds":{"left":0.953125,"top":0.16999201,"width":0.04155585,"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":"AXStaticText","text":"Nikolay Nikolov","depth":17,"bounds":{"left":0.9616024,"top":0.17398244,"width":0.027593086,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"All Envs","depth":13,"bounds":{"left":0.10954122,"top":0.20949721,"width":0.03158245,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"All Envs","depth":17,"bounds":{"left":0.11353058,"top":0.21628092,"width":0.01761968,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"24H","depth":13,"bounds":{"left":0.14079122,"top":0.20949721,"width":0.023105053,"height":0.028731046},"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":"24H","depth":17,"bounds":{"left":0.14478059,"top":0.21628092,"width":0.009142287,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Add a search term","depth":16,"bounds":{"left":0.17719415,"top":0.21428572,"width":0.69714093,"height":0.01915403},"on_screen":true,"help_text":"","placeholder":"Filter events…","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"Add a search term","depth":16,"bounds":{"left":0.17719415,"top":0.21428572,"width":0.69714093,"height":0.01915403},"on_screen":true,"help_text":"","placeholder":"Filter events…","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close sidebar","depth":13,"bounds":{"left":0.88264626,"top":0.20949721,"width":0.011968086,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Toggle graph series - Events","depth":12,"bounds":{"left":0.11386303,"top":0.25818038,"width":0.021276595,"height":0.035115723},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Events","depth":15,"bounds":{"left":0.1178524,"top":0.26256984,"width":0.013297873,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"66","depth":15,"bounds":{"left":0.12117686,"top":0.27693537,"width":0.0066489363,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Toggle graph series - Users","depth":12,"bounds":{"left":0.11386303,"top":0.2980846,"width":0.021276595,"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":"Users","depth":15,"bounds":{"left":0.119015954,"top":0.3008779,"width":0.010970744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":15,"bounds":{"left":0.12267287,"top":0.31524342,"width":0.0034906915,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"release 9% 881233","depth":12,"bounds":{"left":0.7669548,"top":0.25818038,"width":0.11702128,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"release","depth":14,"bounds":{"left":0.76894945,"top":0.25977653,"width":0.013962766,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9%","depth":14,"bounds":{"left":0.83826464,"top":0.25977653,"width":0.005485372,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"881233","depth":14,"bounds":{"left":0.8450798,"top":0.25977653,"width":0.013962766,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"environment 73% production","depth":12,"bounds":{"left":0.7669548,"top":0.2725459,"width":0.11702128,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"environment","depth":14,"bounds":{"left":0.76894945,"top":0.273743,"width":0.024767287,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"73%","depth":14,"bounds":{"left":0.83577126,"top":0.273743,"width":0.007978723,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"production","depth":14,"bounds":{"left":0.8450798,"top":0.273743,"width":0.020279255,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"runtime.name 100% php","depth":12,"bounds":{"left":0.7669548,"top":0.2869114,"width":0.11702128,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"runtime.name","depth":14,"bounds":{"left":0.76894945,"top":0.28810853,"width":0.027094414,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"100%","depth":14,"bounds":{"left":0.83327794,"top":0.28810853,"width":0.010472074,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"php","depth":14,"bounds":{"left":0.8450798,"top":0.28810853,"width":0.0071476065,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"os 55% Linux 6.1.164-196.303.amzn2023.aarch64","depth":12,"bounds":{"left":0.7669548,"top":0.3008779,"width":0.11702128,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"os","depth":14,"bounds":{"left":0.76894945,"top":0.30247405,"width":0.004488032,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"55%","depth":14,"bounds":{"left":0.83577126,"top":0.30247405,"width":0.007978723,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Linux 6.1.164-196.303.amzn2023.aarch64","depth":14,"bounds":{"left":0.8450798,"top":0.30247405,"width":0.07712766,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"View all tags","depth":12,"bounds":{"left":0.76894945,"top":0.31763768,"width":0.027094414,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"View all tags","depth":13,"bounds":{"left":0.76894945,"top":0.31923383,"width":0.027094414,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Select issue content","depth":13,"bounds":{"left":0.10954122,"top":0.34836394,"width":0.028922873,"height":0.025538707},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Events","depth":15,"bounds":{"left":0.11353058,"top":0.35434955,"width":0.01761968,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open in Discover","depth":13,"bounds":{"left":0.82430184,"top":0.3499601,"width":0.04338431,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Open in Discover","depth":15,"bounds":{"left":0.83294547,"top":0.35514766,"width":0.032081116,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Return to event details","depth":13,"bounds":{"left":0.8703458,"top":0.3499601,"width":0.015957447,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Close","depth":15,"bounds":{"left":0.87300533,"top":0.35514766,"width":0.010638298,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"All Events","depth":14,"bounds":{"left":0.11386303,"top":0.38946527,"width":0.022273935,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Showing","depth":13,"bounds":{"left":0.79172206,"top":0.39026338,"width":0.017121011,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.8088431,"top":0.39026338,"width":0.0016622341,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":13,"bounds":{"left":0.81050533,"top":0.39026338,"width":0.0018284575,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"50","depth":13,"bounds":{"left":0.81233376,"top":0.39026338,"width":0.004986702,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"of","depth":13,"bounds":{"left":0.81732047,"top":0.39026338,"width":0.0056515955,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"66","depth":13,"bounds":{"left":0.82297206,"top":0.39026338,"width":0.0048204786,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"matching","depth":13,"bounds":{"left":0.8277925,"top":0.39026338,"width":0.019780586,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"events","depth":13,"bounds":{"left":0.84757316,"top":0.39026338,"width":0.012466756,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Previous Page","depth":13,"bounds":{"left":0.8640292,"top":0.38427773,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Next Page","depth":13,"bounds":{"left":0.87400264,"top":0.38427773,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Event ID","depth":16,"bounds":{"left":0.11386303,"top":0.42218676,"width":0.018783245,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Timestamp","depth":15,"bounds":{"left":0.1471077,"top":0.42218676,"width":0.06482713,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Timestamp","depth":16,"bounds":{"left":0.1471077,"top":0.42218676,"width":0.025099734,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Title","depth":15,"bounds":{"left":0.22024602,"top":0.42218676,"width":0.05817819,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Title","depth":16,"bounds":{"left":0.22024602,"top":0.42218676,"width":0.009973404,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Transaction","depth":15,"bounds":{"left":0.2867354,"top":0.42218676,"width":0.05817819,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Transaction","depth":16,"bounds":{"left":0.2867354,"top":0.42218676,"width":0.026595745,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Release","depth":15,"bounds":{"left":0.35322472,"top":0.42218676,"width":0.04155585,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Release","depth":16,"bounds":{"left":0.35322472,"top":0.42218676,"width":0.01761968,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Environment","depth":15,"bounds":{"left":0.40309176,"top":0.42218676,"width":0.029920213,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Environment","depth":16,"bounds":{"left":0.40309176,"top":0.42218676,"width":0.029089095,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User","depth":15,"bounds":{"left":0.44132313,"top":0.42218676,"width":0.04155585,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User","depth":16,"bounds":{"left":0.44132313,"top":0.42218676,"width":0.010472074,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Device","depth":15,"bounds":{"left":0.49119017,"top":0.42218676,"width":0.04155585,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Device","depth":16,"bounds":{"left":0.49119017,"top":0.42218676,"width":0.01512633,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"OS","depth":15,"bounds":{"left":0.54105717,"top":0.42218676,"width":0.04155585,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"OS","depth":16,"bounds":{"left":0.54105717,"top":0.42218676,"width":0.006150266,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"URL","depth":15,"bounds":{"left":0.5909242,"top":0.42218676,"width":0.09142287,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"URL","depth":16,"bounds":{"left":0.5909242,"top":0.42218676,"width":0.009142287,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Runtime","depth":15,"bounds":{"left":0.6906583,"top":0.42218676,"width":0.04155585,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Runtime","depth":16,"bounds":{"left":0.6906583,"top":0.42218676,"width":0.019115692,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8243559861745003706
|
-2433818861762675516
|
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
Close tab
CloudWatch | us-east-2
CloudWatch | us-east-2
test (885333) - jiminny/app
test (885333) - 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
Userpilot | Events
Userpilot | Events
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Toggle organization menu
Issues
Issues
Explore
Explore
Dashboards
Dashboards
Monitors
Monitors
Settings
Settings
Try Business
What's New
Help
[EMAIL]
Issues
Expand
Feed
Feed
Errors & Outages
Errors & Outages
Breached Metrics
Breached Metrics
Warnings
Warnings
User Feedback
User Feedback
Autofix
Autofix
Recently Run
Recently Run
All Views
All Views
Configure
Alerts Moved
Alerts
Moved
Issues
Issues
View Project Details
APP-1DTF
Ask Seer
Ask Seer
/
Give Feedback
TypeError
View events
Events (total)
Users (90d)
Level: Error
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
2.4K
0
Ongoing
/app/Jobs/AutomatedReports/SendReportJob.php in Jiminny\Jobs\AutomatedReports\SendReportJob::handle
Quick Fix
Resolve
Resolve
More resolve options
Archive
Archive
Archive options
Subscribe
Share
More Actions
Priority
Modify issue priority
High
Assignee
Modify issue assignee
Nikolay Nikolov
All Envs
All Envs
24H
24H
Add a search term
Add a search term
Close sidebar
Toggle graph series - Events
Events
66
Toggle graph series - Users
Users
0
release 9% 881233
release
9%
881233
environment 73% production
environment
73%
production
runtime.name 100% php
runtime.name
100%
php
os 55% Linux 6.1.164-196.303.amzn2023.aarch64
os
55%
Linux 6.1.164-196.303.amzn2023.aarch64
View all tags
View all tags
Select issue content
Events
Open in Discover
Open in Discover
Return to event details
Close
All Events
Showing
1
-
50
of
66
matching
events
Previous Page
Next Page
Event ID
Timestamp
Timestamp
Title
Title
Transaction
Transaction
Release
Release
Environment
Environment
User
User
Device
Device
OS
OS
URL
URL
Runtime
Runtime...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
27725
|
NULL
|
0
|
2026-05-12T14:37:13.097524+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778596633097_m1.jpg...
|
Finder
|
.screenpipe
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778596633097_m1.jpg...
|
Favourites
jiminny
AirDrop
Recents
Applications
Do Favourites
jiminny
AirDrop
Recents
Applications
Documents
Downloads
lukas
iCloud
iCloud Drive
Sync folder
Locations
DXP4800PLUS-B5F
Eject
Network
Tags
CRM
Orange
Red
Yellow
Green
Blue
Purple
All Tags…
Name
Date Modified
Size
Kind
screenpipe.2026-05-12.0.log
Today at 17:37
243 KB
Log File
db.sqlite-wal
Today at 17:37
9,5 MB
Document
data
Today at 17:37
1,81 GB
Folder
db.sqlite
Today at 17:36
4,45 GB
Document
db.sqlite-shm
Today at 9:26
66 KB...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Favourites","depth":6,"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"jiminny","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AirDrop","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Recents","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Applications","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Documents","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Downloads","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"lukas","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"iCloud","depth":6,"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"iCloud Drive","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sync folder","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Locations","depth":6,"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"DXP4800PLUS-B5F","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Eject","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false},{"role":"AXStaticText","text":"Network","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Tags","depth":6,"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"CRM","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Orange","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Red","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Yellow","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Green","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Blue","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Purple","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"All Tags…","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Name","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Date Modified","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Size","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Kind","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"screenpipe.2026-05-12.0.log","depth":7,"on_screen":true,"value":"screenpipe.2026-05-12.0.log","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Today at 17:37","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"243 KB","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Log File","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"db.sqlite-wal","depth":7,"on_screen":true,"value":"db.sqlite-wal","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Today at 17:37","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"9,5 MB","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Document","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"data","depth":7,"on_screen":true,"value":"data","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Today at 17:37","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1,81 GB","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Folder","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"db.sqlite","depth":7,"on_screen":true,"value":"db.sqlite","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Today at 17:36","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4,45 GB","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Document","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"db.sqlite-shm","depth":7,"on_screen":true,"value":"db.sqlite-shm","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Today at 9:26","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"66 KB","depth":7,"on_screen":true,"role_description":"text"}]...
|
-8243511941762875824
|
-1246892623299255405
|
click
|
accessibility
|
NULL
|
Favourites
jiminny
AirDrop
Recents
Applications
Do Favourites
jiminny
AirDrop
Recents
Applications
Documents
Downloads
lukas
iCloud
iCloud Drive
Sync folder
Locations
DXP4800PLUS-B5F
Eject
Network
Tags
CRM
Orange
Red
Yellow
Green
Blue
Purple
All Tags…
Name
Date Modified
Size
Kind
screenpipe.2026-05-12.0.log
Today at 17:37
243 KB
Log File
db.sqlite-wal
Today at 17:37
9,5 MB
Document
data
Today at 17:37
1,81 GB
Folder
db.sqlite
Today at 17:36
4,45 GB
Document
db.sqlite-shm
Today at 9:26
66 KB...
|
27723
|
NULL
|
NULL
|
NULL
|
|
23380
|
986
|
23
|
2026-05-12T07:48:16.987035+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778572096987_m1.jpg...
|
Slack
|
Steliyan Georgiev (DM) - Jiminny Inc - 4 new items Steliyan Georgiev (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
Steliyan Georgiev
Petko Kashinski
Galya Dimitrova
Aneliya Angelova
Stefka Stoyanova
Vasil Vasilev
Nikolay Ivanov
Aneliya Angelova
,
Nikolay Yankov
,
Steliyan Georgiev
Stoyan Tanev
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":14,"bounds":{"left":0.51180553,"top":0.08111111,"width":0.025,"height":0.04},"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.50625,"top":0.14,"width":0.036111113,"height":0.075555556},"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.5138889,"top":0.19222222,"width":0.020833334,"height":0.015555556},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":14,"bounds":{"left":0.50625,"top":0.21555555,"width":0.036111113,"height":0.075555556},"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.5159722,"top":0.26777777,"width":0.016666668,"height":0.015555556},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":14,"bounds":{"left":0.50625,"top":0.2911111,"width":0.036111113,"height":0.075555556},"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.51111114,"top":0.34333333,"width":0.027083334,"height":0.015555556},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.51111114,"top":0.34333333,"width":0.0055555557,"height":0.015555556}},{"char_start":1,"char_count":7,"bounds":{"left":0.5159722,"top":0.34333333,"width":0.022222223,"height":0.015555556}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":14,"bounds":{"left":0.50625,"top":0.36666667,"width":0.036111113,"height":0.075555556},"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.51666665,"top":0.4188889,"width":0.015972223,"height":0.015555556},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.51666665,"top":0.4188889,"width":0.004166667,"height":0.015555556}},{"char_start":1,"char_count":4,"bounds":{"left":0.5208333,"top":0.4188889,"width":0.011805556,"height":0.015555556}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":14,"bounds":{"left":0.50625,"top":0.4422222,"width":0.036111113,"height":0.075555556},"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.5152778,"top":0.49444443,"width":0.018055556,"height":0.015555556},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":14,"bounds":{"left":0.50625,"top":0.5177778,"width":0.036111113,"height":0.075555556},"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.5152778,"top":0.57,"width":0.01875,"height":0.015555556},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.038194444,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.036805555,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.038194444,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.06111111,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":21,"bounds":{"left":0.68472224,"top":0.12777779,"width":0.0055555557,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.050694443,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-x-integration-app","depth":23,"bounds":{"left":0.58819443,"top":0.21666667,"width":0.09166667,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.21666667,"width":0.0027777778,"height":0.02}},{"char_start":1,"char_count":24,"bounds":{"left":0.59097224,"top":0.21666667,"width":0.11319444,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":23,"bounds":{"left":0.58819443,"top":0.24777777,"width":0.093055554,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":23,"bounds":{"left":0.58819443,"top":0.3211111,"width":0.046527777,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":23,"bounds":{"left":0.58819443,"top":0.35222223,"width":0.025694445,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.35222223,"width":0.0055555557,"height":0.02}},{"char_start":1,"char_count":5,"bounds":{"left":0.59375,"top":0.35222223,"width":0.019444445,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":23,"bounds":{"left":0.58819443,"top":0.38333333,"width":0.038194444,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":23,"bounds":{"left":0.58819443,"top":0.41444445,"width":0.022222223,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":23,"bounds":{"left":0.58819443,"top":0.44555557,"width":0.072222225,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.44555557,"width":0.0048611113,"height":0.02}},{"char_start":1,"char_count":15,"bounds":{"left":0.59305555,"top":0.44555557,"width":0.06736111,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"curiosity_lab","depth":23,"bounds":{"left":0.58819443,"top":0.47666666,"width":0.057638887,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.47666666,"width":0.0048611113,"height":0.02}},{"char_start":1,"char_count":12,"bounds":{"left":0.59305555,"top":0.47666666,"width":0.05277778,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":23,"bounds":{"left":0.58819443,"top":0.50777775,"width":0.054166667,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":23,"bounds":{"left":0.58819443,"top":0.5388889,"width":0.034027778,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":23,"bounds":{"left":0.58819443,"top":0.57,"width":0.048611112,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":23,"bounds":{"left":0.58819443,"top":0.6011111,"width":0.072916664,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.6011111,"width":0.00625,"height":0.02}},{"char_start":1,"char_count":15,"bounds":{"left":0.59444445,"top":0.6011111,"width":0.06666667,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":23,"bounds":{"left":0.58819443,"top":0.63222224,"width":0.08055556,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"random","depth":23,"bounds":{"left":0.58819443,"top":0.66333336,"width":0.035416666,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":23,"bounds":{"left":0.58819443,"top":0.6944444,"width":0.036805555,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"sofia-office","depth":23,"bounds":{"left":0.58819443,"top":0.72555554,"width":0.05138889,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.72555554,"width":0.0048611113,"height":0.02}},{"char_start":1,"char_count":11,"bounds":{"left":0.59305555,"top":0.72555554,"width":0.045833334,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"support","depth":23,"bounds":{"left":0.58819443,"top":0.75666666,"width":0.036111113,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":23,"bounds":{"left":0.58819443,"top":0.7877778,"width":0.05138889,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":23,"bounds":{"left":0.58819443,"top":0.8188889,"width":0.094444446,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.8188889,"width":0.004166667,"height":0.02}},{"char_start":1,"char_count":20,"bounds":{"left":0.5923611,"top":0.8188889,"width":0.09861111,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":23,"bounds":{"left":0.58819443,"top":0.8922222,"width":0.07986111,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":23,"bounds":{"left":0.58819443,"top":0.92333335,"width":0.072222225,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":23,"bounds":{"left":0.58819443,"top":0.95444447,"width":0.07361111,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":23,"bounds":{"left":0.58819443,"top":0.9855555,"width":0.07847222,"height":0.008888889},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":23,"on_screen":false,"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":false,"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"you","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Google Calendar","depth":23,"on_screen":false,"role_description":"text"}]...
|
-8243473094329632248
|
-3513699419552080213
|
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
Steliyan Georgiev
Petko Kashinski
Galya Dimitrova
Aneliya Angelova
Stefka Stoyanova
Vasil Vasilev
Nikolay Ivanov
Aneliya Angelova
,
Nikolay Yankov
,
Steliyan Georgiev
Stoyan Tanev
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
SlackFileEditViewGoHistoryWindowHelpDOCKERO ₴1DEV (-zsh)O $2APP (-zsh)whisper_init_state:compute buffer(decode) =96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu: device 0: Metal (type: 1)whisper_backend_init_gpu: found GPU device 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init:found device: Apple M1ggml_metal_init:pickingdefault device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrency= trueggml_metal_init: use graph optimizetruewhisper_backend_init: using BLAS backendwhisper_init_state: kv selfsize=3.15MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize=2.36 MBwhisper_init_state: compute buffer (conv)=whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu: device 0: Metal (type: 1)whisper_backend_init_gpu: found GPU device 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init: use fusion= trueggml_metal_init: use concurrency= trueggml_metal_init: use graph optimize = truewhisper_backend_init: using BLAS backendwhisper_init_state: kv self size3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize=2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu: device 0: Metal (type: 1)whisper_backend_init_gpu: found GPU device 0: Metal(type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init: use fusiontrue883screen-zsh•HomeDMsActivityFilesLater.••More+lbl§ Support Daily - in 4h 12 m100% (Tue 12 May 10:48:16ED→QDescribe what you are looking forJiminny ...External connections* Starred& jiminny-x-integrati...8 platform-inner-teamChannels# 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 jimi...• Direct messagesRo Steliyan GeorgievPetko KashinskiGalya DimitrovaSteliyan Georgiev6 0• MessagesAdd canvasO Files+pdf_url на репорToday ~може ли по-кьсно да се чуем да видим каквоможе да направимSteliyan Georgiev 10:44 AMЗдрасти Лукаш, даима ли тикет?Lukas Kovalik 10:46 AMhttps://jiminny.atlassian.net/browse/JY-20776Jira CloudAutomated report - sentryS Bug JY-20776 in Jira CloudStatusPriorityBacklog= MediumAssigneeUnassignedAs of today at 10:46 AMOpen in JiraSummariseпроблем беше че няма pdf_url сега ще серазровя за конкретен репорти идеята е на РНР да не го пробваме през час ноГаля попита за регенериранепредполагам че е нещо случайно най-вероятносамо един репорт..•Shift + Return to add a new linTOD...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
14360
|
637
|
18
|
2026-05-09T17:24:31.710251+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778347471710_m1.jpg...
|
Firefox
|
lakylak/finance-hub - finance-hub - Gitea: Git wit lakylak/finance-hub - finance-hub - Gitea: Git with a cup of tea — Personal...
|
True
|
gitea.com/lakylak/finance-hub
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Pull requests · screenpipe/screenpipe · GitHub
Clo Pull requests · screenpipe/screenpipe · GitHub
Close tab
DNS / Nameservers | Hostinger
Close tab
Nginx Proxy Manager
Close tab
Screenpipe — Archive
Close tab
SQLite Web: archive.db
Close tab
SQLite Web: db.sqlite
Close tab
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
Close tab
DXP4800PLUS-B5F8
Close tab
AFFiNE - All In One KnowledgeOS
Close tab
All docs · AFFiNE
Close tab
Payments Logger
Close tab
Your old PC can run Windows 11 in a VM, but not on bare metal - [EMAIL] - Gmail
Close tab
Location Logger
Close tab
Finance Hub
Close tab
Finance Hub
Close tab
Select: transactions - db - Adminer
Close tab
Claude Code | Claude Platform
Close tab
April 2026 spending by category - Claude
Close tab
lakylak/finance-hub - finance-hub - Gitea: Git with a cup of tea
Close tab
Applications - Admin - authentik
Close tab
New Tab
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Customize sidebar
Dashboard
Issues
Issues
Pull Requests
Pull Requests
Milestones
Milestones
Explore
Explore
Notifications
lakylak
lakylak
/
finance-hub
finance-hub
Private
RSS Feed
Unwatch
1
1
Star
0
0
Fork
Fork
0
0
Code
Code
Issues
Issues
Pull Requests
Pull Requests
Actions
Actions
Projects
Projects
Releases
Releases
Wiki
Wiki
Activity
Activity
Settings
Settings
3 Commits
3
Commits
1 Branch
1
Branch
0 Tags
0
Tags
main
New Pull Request
Go to file
Code
Code
Lukas Kovalik
640e0d609d
640e0d609d
Add Authentik auth, API key support, and remote MCP server
Add Authentik auth, API key support, and remote MCP server
...
2 minutes ago
backend
backend
Add Authentik auth, API key support, and remote MCP server
Add Authentik auth, API key support, and remote MCP server
2 minutes ago
frontend
frontend
Initial commit: finance-hub unified finance app
Initial commit: finance-hub unified finance app
1 hour ago
mcp
mcp
Add Authentik auth, API key support, and remote MCP server
Add Authentik auth, API key support, and remote MCP server
2 minutes ago
scripts
scripts
Initial commit: finance-hub unified finance app
Initial commit: finance-hub unified finance app
1 hour ago
.env.example
.env.example
Add Authentik auth, API key support, and remote MCP server
Add Authentik auth, API key support, and remote MCP server
2 minutes ago
.gitignore
.gitignore
Add Authentik auth, API key support, and remote MCP server
Add Authentik auth, API key support, and remote MCP server
2 minutes ago
docker-compose.yml
docker-compose.yml
Add Authentik auth, API key support, and remote MCP server
Add Authentik auth, API key support, and remote MCP server
2 minutes ago
README.md
README.md
Add README with project description, API reference, and usage guide
Add README with project description, API reference, and usage guide
1 hour ago
README.md Escape Edit File
README.md
README.md
Escape
Edit File
Finance Hub
Finance Hub
Unified personal finance tracker that consolidates DSK Bank SMS notifications and CSV statement exports into a single PostgreSQL database with a React review UI.
Replaces two separate tools:
payments-logger
— ingested DSK Bank SMS notifications
dsk-uploader
— parsed DSK Bank CSV exports and sent them to Notion
Features
Features
SMS ingest
— receives DSK Bank payment SMS via iOS Shortcuts / HTTP POST; parses amount, recipient, card, date, balance
CSV upload
— drag-and-drop DSK Bank account statement exports (BGN and EUR formats, cp1251 and UTF-8 encodings)
Deduplication
— exact
rawMessage
match prevents duplicate imports from re-uploads or re-runs of the reimport script
Auto-tagging
— new imports for a known recipient are automatically tagged based on tag history for that payee
Rule-based tagging
— CSV rows are auto-tagged by keyword rules (LIDL → Groceries, NETFLIX → Subscriptions, etc.)
Deduplication display
— same-day same-amount records from SMS and CSV are shown as a single "SMS + CSV" row in the UI
Notification forwarding
— sends payment summaries to a configurable notifier service (Viber, etc.)
Tag management
— create, colour-code, and remove tags on individual transactions
Settings
— column visibility, source row colouring, table density, mobile layout, hide balance-alert SMS
Auth
— delegated to Authentik via NPM reverse proxy header injection; no local user accounts
Tech Stack
Tech Stack
Layer
Technology
Backend
Node.js 20, Express, Prisma 5
Database
PostgreSQL 16
CSV parsing
csv-parse
,
iconv-lite
(cp1251 + UTF-8 BOM)
File upload
multer
(memory storage)
Frontend
React 18, Vite, Tailwind CSS, Lucide React
Auth
Authentik forward-auth via
X-authentik-username
header
Container
Docker Compose
Layer
Backend
Database
CSV parsing
File upload
Frontend
Auth
Container
Technology
Node.js 20, Express, Prisma 5
PostgreSQL 16
csv-parse
,
iconv-lite
(cp1251 + UTF-8 BOM)
multer
(memory storage)
React 18, Vite, Tailwind CSS, Lucide React
Authentik forward-auth via
X-authentik-username
header
Docker Compose
Quick Start
Quick Start
1. Clone and configure
1. Clone and configure
git clone [EMAIL]:lakylak/finance-hub.git
cd
finance-hub
cp .env.example .env
# Edit .env — set DB_PASSWORD and notifier settings
2. Start
2. Start
docker compose up -d --build
Services:
Service
Default port
Frontend
5175
Backend API
3001
Adminer (DB UI)
8092
Service
Frontend
Backend API
Adminer (DB UI)
Default port
5175
3001
8092
3. First run
3. First run
Prisma migrations run automatically on backend startup via
prisma migrate deploy
.
Environment variables
Environment variables
Variable
Required
Description
DB_PASSWORD
Yes
PostgreSQL password
NOTIFIER_URL
No
Base URL of the notifier service
NOTIFIER_CHANNEL
No
Channel to use (
viber
, etc.) Default:
viber
NOTIFY_DEFAULT_PHONE
No
Phone number for payment notifications
TZ
No
Timezone for SMS date parsing. Default:
Europe/Sofia
BACKEND_PORT
No
Backend listen port. Default:
3001
FRONTEND_PORT
No
Frontend listen port. Default:
5175
DEV_BYPASS_AUTH
No
Set
true
to skip Authentik header check during local dev
Variable
DB_PASSWORD
NOTIFIER_URL
NOTIFIER_CHANNEL
NOTIFY_DEFAULT_PHONE
TZ
BACKEND_PORT
FRONTEND_PORT
DEV_BYPASS_AUTH
Required
Yes
No
No
No
No
No
No
No
Description
PostgreSQL password
Base URL of the notifier service
Channel to use (
viber
, etc.) Default:
viber
Phone number for payment notifications
Timezone for SMS date parsing. Default:
Europe/Sofia
Backend listen port. Default:
3001
Frontend listen port. Default:
5175
Set
true
to skip Authentik header check during local dev
Authentication
Authentication
In production, route the frontend through
Nginx Proxy Manager
with an
Authentik forward-auth
provider. NPM injects
X-authentik-username
(and optionally
X-authentik-email
,
X-authentik-groups
) into every proxied request.
The backend reads these headers and rejects requests without them (unless
DEV_BYPASS_AUTH=true
).
The public endpoints below are exempt and require no authentication:
GET /api/health
POST /api/payments/ingest
Sign-out link:
/outpost.goauthentik.io/sign_out
API Reference
API Reference
Health
Health
GET /api/health
GET /api/health
Public. Returns service status and database connection info.
{
"status"
:
"ok"
,
"timestamp"
:
"2026-05-09T10:00:00.000Z"
,
"storage"
:
{
"type"
:
"PostgreSQL"
,
"host"
:
"db"
,
"database"
:
"finance_hub"
}
}
Payments (Transaction Imports)
Payments (Transaction Imports)
Base path:
/api/payments
All endpoints require authentication except
/ingest
.
POST /api/payments/ingest
POST /api/payments/ingest
Public.
Ingest a DSK Bank SMS notification or structured (Apple Wallet) payment.
Rate limited to
200 requests/minute
.
Returns
409
if the exact message was already imported.
SMS body:
{
"message"
:
"DSK Bank. Na 08/05/2026 v 19:32 sa plateni 67.81 EUR s karta 400915***4447 na POS s adres: LIDL BALGARIYA EOOD, SOFIYA, BGR. Nalichni: 2011.57 EUR."
}
Structured (Apple Wallet) body:
{
"ingestMode"
:
"apple_wallet"
,
"amount"
:
12.50
,
"recipient"
:
"Starbucks"
,
"type"
:
"WALLET"
,
"card"
:
"4444"
,
"date"
:
"2026-05-09T10:30:00Z"
,
"balance"
:
null
}
Response:
201 Created
— the created import record.
Duplicate:
409 Conflict
—
{ "error": "Already imported", "existing": { ... } }
GET /api/payments
GET /api/payments
List transaction imports with filtering, sorting, and pagination.
Query parameters:
Parameter
Type
Description
page
int
Page number. Default:
1
limit
int
Records per page, max 200. Default:
50
sortBy
string
Field to sort by:
date
,
amount
,
balance
,
recipient
,
type
,
source
,
createdAt
,
status
. Default:
createdAt
sortDir
string
asc
or
desc
. Default:
desc
status
string
Filter by status:
UNPROCESSED
,
SENT
,
SKIPPED
source
string
Filter by source:
INGEST
,
UPLOAD
type
string
Filter by transaction type (e.g.
POS
,
ATM
)
tag
string
Filter by tag name
recipient
string
Case-insensitive substring match on recipient
search
string
Case-insensitive search across
rawMessage
and
recipient
dateFrom
date
ISO date string — inclusive start of date range
dateTo
date
ISO date string — inclusive end of date range (interpreted as end of day)
hideBalanceAlerts
boolean
true
to exclude balance-notification SMS and records with no parsed amount
Parameter
page
limit
sortBy
sortDir
status
source
type
tag
recipient
search
dateFrom
dateTo
hideBalanceAlerts
Type
int
int
string
string
string
string
string
string
string
string
date
date
boolean
Description
Page number. Default:
1
Records per page, max 200. Default:
50
Field to sort by:
date
,
amount
,
balance
,
recipient
,
type
,
source
,...
|
[{"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":"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":"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":"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":"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":"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":"Screenpipe — Archive","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"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":"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":"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":"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":"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":"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":"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":"DXP4800PLUS-B5F8","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"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":"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":"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":"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":"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":"Payments Logger","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"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":"Your old PC can run Windows 11 in a VM, but not on bare metal - 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":"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":"Location Logger","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"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":"Finance Hub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"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":"Finance Hub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"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":"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":"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":"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":"April 2026 spending by category - Claude","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"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":"lakylak/finance-hub - finance-hub - Gitea: Git with a cup of tea","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Applications - Admin - authentik","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"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":"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":"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":"AXLink","text":"Dashboard","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Issues","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull Requests","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull Requests","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Milestones","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Milestones","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Notifications","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"lakylak","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"lakylak","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":7,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"finance-hub","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"finance-hub","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Private","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"RSS Feed","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Unwatch","depth":7,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"1","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Star","depth":7,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"0","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Fork","depth":8,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fork","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"0","depth":8,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0","depth":9,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":8,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Issues","depth":8,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull Requests","depth":8,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull Requests","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":8,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Projects","depth":8,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Projects","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Releases","depth":8,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Releases","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":8,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Activity","depth":8,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Activity","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":8,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 Commits","depth":8,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Commits","depth":9,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 Branch","depth":8,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Branch","depth":9,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"0 Tags","depth":8,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Tags","depth":9,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"main","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Pull Request","depth":7,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Go to file","depth":9,"on_screen":false,"help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code","depth":7,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Code","depth":9,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"640e0d609d","depth":9,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"640e0d609d","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add Authentik auth, API key support, and remote MCP server","depth":11,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add Authentik auth, API key support, and remote MCP server","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"...","depth":10,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2 minutes ago","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"backend","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"backend","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add Authentik auth, API key support, and remote MCP server","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add Authentik auth, API key support, and remote MCP server","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2 minutes ago","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"frontend","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"frontend","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Initial commit: finance-hub unified finance app","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Initial commit: finance-hub unified finance app","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 hour ago","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"mcp","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"mcp","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add Authentik auth, API key support, and remote MCP server","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add Authentik auth, API key support, and remote MCP server","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2 minutes ago","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"scripts","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"scripts","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Initial commit: finance-hub unified finance app","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Initial commit: finance-hub unified finance app","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 hour ago","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":".env.example","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":".env.example","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add Authentik auth, API key support, and remote MCP server","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add Authentik auth, API key support, and remote MCP server","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2 minutes ago","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":".gitignore","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":".gitignore","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add Authentik auth, API key support, and remote MCP server","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add Authentik auth, API key support, and remote MCP server","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2 minutes ago","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"docker-compose.yml","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"docker-compose.yml","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add Authentik auth, API key support, and remote MCP server","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add Authentik auth, API key support, and remote MCP server","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2 minutes ago","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"README.md","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"README.md","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add README with project description, API reference, and usage guide","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add README with project description, API reference, and usage guide","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 hour ago","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"README.md Escape Edit File","depth":8,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"README.md","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"README.md","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Escape","depth":9,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Edit File","depth":9,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Finance Hub","depth":9,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Finance Hub","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unified personal finance tracker that consolidates DSK Bank SMS notifications and CSV statement exports into a single PostgreSQL database with a React review UI.","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Replaces two separate tools:","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"payments-logger","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— ingested DSK Bank SMS notifications","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dsk-uploader","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— parsed DSK Bank CSV exports and sent them to Notion","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Features","depth":9,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Features","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SMS ingest","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— receives DSK Bank payment SMS via iOS Shortcuts / HTTP POST; parses amount, recipient, card, date, balance","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CSV upload","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— drag-and-drop DSK Bank account statement exports (BGN and EUR formats, cp1251 and UTF-8 encodings)","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Deduplication","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— exact","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"rawMessage","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"match prevents duplicate imports from re-uploads or re-runs of the reimport script","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Auto-tagging","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— new imports for a known recipient are automatically tagged based on tag history for that payee","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Rule-based tagging","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— CSV rows are auto-tagged by keyword rules (LIDL → Groceries, NETFLIX → Subscriptions, etc.)","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Deduplication display","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— same-day same-amount records from SMS and CSV are shown as a single \"SMS + CSV\" row in the UI","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Notification forwarding","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— sends payment summaries to a configurable notifier service (Viber, etc.)","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Tag management","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— create, colour-code, and remove tags on individual transactions","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Settings","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— column visibility, source row colouring, table density, mobile layout, hide balance-alert SMS","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Auth","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— delegated to Authentik via NPM reverse proxy header injection; no local user accounts","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Tech Stack","depth":9,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Tech Stack","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Layer","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Technology","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Backend","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Node.js 20, Express, Prisma 5","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Database","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PostgreSQL 16","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CSV parsing","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"csv-parse","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"iconv-lite","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(cp1251 + UTF-8 BOM)","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"File upload","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"multer","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(memory storage)","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Frontend","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"React 18, Vite, Tailwind CSS, Lucide React","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Auth","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Authentik forward-auth via","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"X-authentik-username","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"header","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Container","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Docker Compose","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Layer","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Backend","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Database","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CSV parsing","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"File upload","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Frontend","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Auth","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Container","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Technology","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Node.js 20, Express, Prisma 5","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PostgreSQL 16","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"csv-parse","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"iconv-lite","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(cp1251 + UTF-8 BOM)","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"multer","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(memory storage)","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"React 18, Vite, Tailwind CSS, Lucide React","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Authentik forward-auth via","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"X-authentik-username","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"header","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Docker Compose","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Quick Start","depth":9,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Quick Start","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. Clone and configure","depth":9,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. Clone and configure","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"git clone git@gitea.com:lakylak/finance-hub.git","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"cd","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"finance-hub\ncp .env.example .env","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"# Edit .env — set DB_PASSWORD and notifier settings","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. Start","depth":9,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. Start","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"docker compose up -d --build","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Services:","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Service","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Default port","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Frontend","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5175","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Backend API","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3001","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Adminer (DB UI)","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8092","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Service","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Frontend","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Backend API","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Adminer (DB UI)","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Default port","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5175","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3001","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8092","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"3. First run","depth":9,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3. First run","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Prisma migrations run automatically on backend startup via","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"prisma migrate deploy","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Environment variables","depth":9,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Environment variables","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Variable","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Required","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Description","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DB_PASSWORD","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Yes","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PostgreSQL password","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NOTIFIER_URL","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Base URL of the notifier service","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NOTIFIER_CHANNEL","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Channel to use (","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"viber","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", etc.) Default:","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"viber","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NOTIFY_DEFAULT_PHONE","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Phone number for payment notifications","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TZ","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Timezone for SMS date parsing. Default:","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Europe/Sofia","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BACKEND_PORT","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Backend listen port. Default:","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3001","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FRONTEND_PORT","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Frontend listen port. Default:","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5175","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DEV_BYPASS_AUTH","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Set","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"true","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to skip Authentik header check during local dev","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Variable","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DB_PASSWORD","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NOTIFIER_URL","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NOTIFIER_CHANNEL","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NOTIFY_DEFAULT_PHONE","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TZ","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BACKEND_PORT","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FRONTEND_PORT","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DEV_BYPASS_AUTH","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Required","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Yes","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Description","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PostgreSQL password","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Base URL of the notifier service","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Channel to use (","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"viber","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", etc.) Default:","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"viber","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Phone number for payment notifications","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Timezone for SMS date parsing. Default:","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Europe/Sofia","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Backend listen port. Default:","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3001","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Frontend listen port. Default:","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5175","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Set","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"true","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to skip Authentik header check during local dev","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Authentication","depth":9,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Authentication","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"In production, route the frontend through","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nginx Proxy Manager","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"with an","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Authentik forward-auth","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"provider. NPM injects","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"X-authentik-username","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(and optionally","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"X-authentik-email","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"X-authentik-groups","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") into every proxied request.","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The backend reads these headers and rejects requests without them (unless","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DEV_BYPASS_AUTH=true","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":").","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The public endpoints below are exempt and require no authentication:","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"GET /api/health","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"POST /api/payments/ingest","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sign-out link:","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/outpost.goauthentik.io/sign_out","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"API Reference","depth":9,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"API Reference","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Health","depth":9,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Health","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"GET /api/health","depth":9,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"GET /api/health","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public. Returns service status and database connection info.","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"{","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"status\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"ok\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"timestamp\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"2026-05-09T10:00:00.000Z\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"storage\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"{","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"type\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"PostgreSQL\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"host\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"db\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"database\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"finance_hub\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"}","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"}","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Payments (Transaction Imports)","depth":9,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Payments (Transaction Imports)","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Base path:","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/api/payments","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"All endpoints require authentication except","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/ingest","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"POST /api/payments/ingest","depth":9,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"POST /api/payments/ingest","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Public.","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Ingest a DSK Bank SMS notification or structured (Apple Wallet) payment.","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Rate limited to","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200 requests/minute","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Returns","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"409","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"if the exact message was already imported.","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SMS body:","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"{","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"message\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"DSK Bank. Na 08/05/2026 v 19:32 sa plateni 67.81 EUR s karta 400915***4447 na POS s adres: LIDL BALGARIYA EOOD, SOFIYA, BGR. Nalichni: 2011.57 EUR.\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"}","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Structured (Apple Wallet) body:","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"{","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"ingestMode\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"apple_wallet\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"amount\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12.50","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"recipient\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"Starbucks\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"type\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"WALLET\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"card\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"4444\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"date\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"2026-05-09T10:30:00Z\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"balance\"","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"null","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"}","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Response:","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"201 Created","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— the created import record.","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Duplicate:","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"409 Conflict","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"{ \"error\": \"Already imported\", \"existing\": { ... } }","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"GET /api/payments","depth":9,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"GET /api/payments","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"List transaction imports with filtering, sorting, and pagination.","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Query parameters:","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Parameter","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Type","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Description","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"page","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"int","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Page number. Default:","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"limit","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"int","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Records per page, max 200. Default:","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"50","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"sortBy","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Field to sort by:","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"date","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"amount","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"balance","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"recipient","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"type","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"source","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"createdAt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"status","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":". Default:","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"createdAt","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"sortDir","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"asc","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"or","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"desc","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":". Default:","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"desc","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"status","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Filter by status:","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SENT","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SKIPPED","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"source","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Filter by source:","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"INGEST","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"type","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Filter by transaction type (e.g.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"POS","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ATM","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"tag","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Filter by tag name","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"recipient","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Case-insensitive substring match on recipient","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"search","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Case-insensitive search across","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"rawMessage","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"recipient","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dateFrom","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"date","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ISO date string — inclusive start of date range","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dateTo","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"date","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ISO date string — inclusive end of date range (interpreted as end of day)","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"hideBalanceAlerts","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"boolean","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"true","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to exclude balance-notification SMS and records with no parsed amount","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Parameter","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"page","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"limit","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"sortBy","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"sortDir","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"status","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"source","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"type","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"tag","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"recipient","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"search","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dateFrom","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dateTo","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"hideBalanceAlerts","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Type","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"int","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"int","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"date","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"date","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"boolean","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Description","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Page number. Default:","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Records per page, max 200. Default:","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"50","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Field to sort by:","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"date","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"amount","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"balance","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"recipient","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"type","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"source","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8239807547243362186
|
-430422418760656554
|
idle
|
accessibility
|
NULL
|
Pull requests · screenpipe/screenpipe · GitHub
Clo Pull requests · screenpipe/screenpipe · GitHub
Close tab
DNS / Nameservers | Hostinger
Close tab
Nginx Proxy Manager
Close tab
Screenpipe — Archive
Close tab
SQLite Web: archive.db
Close tab
SQLite Web: db.sqlite
Close tab
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
Close tab
DXP4800PLUS-B5F8
Close tab
AFFiNE - All In One KnowledgeOS
Close tab
All docs · AFFiNE
Close tab
Payments Logger
Close tab
Your old PC can run Windows 11 in a VM, but not on bare metal - [EMAIL] - Gmail
Close tab
Location Logger
Close tab
Finance Hub
Close tab
Finance Hub
Close tab
Select: transactions - db - Adminer
Close tab
Claude Code | Claude Platform
Close tab
April 2026 spending by category - Claude
Close tab
lakylak/finance-hub - finance-hub - Gitea: Git with a cup of tea
Close tab
Applications - Admin - authentik
Close tab
New Tab
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Customize sidebar
Dashboard
Issues
Issues
Pull Requests
Pull Requests
Milestones
Milestones
Explore
Explore
Notifications
lakylak
lakylak
/
finance-hub
finance-hub
Private
RSS Feed
Unwatch
1
1
Star
0
0
Fork
Fork
0
0
Code
Code
Issues
Issues
Pull Requests
Pull Requests
Actions
Actions
Projects
Projects
Releases
Releases
Wiki
Wiki
Activity
Activity
Settings
Settings
3 Commits
3
Commits
1 Branch
1
Branch
0 Tags
0
Tags
main
New Pull Request
Go to file
Code
Code
Lukas Kovalik
640e0d609d
640e0d609d
Add Authentik auth, API key support, and remote MCP server
Add Authentik auth, API key support, and remote MCP server
...
2 minutes ago
backend
backend
Add Authentik auth, API key support, and remote MCP server
Add Authentik auth, API key support, and remote MCP server
2 minutes ago
frontend
frontend
Initial commit: finance-hub unified finance app
Initial commit: finance-hub unified finance app
1 hour ago
mcp
mcp
Add Authentik auth, API key support, and remote MCP server
Add Authentik auth, API key support, and remote MCP server
2 minutes ago
scripts
scripts
Initial commit: finance-hub unified finance app
Initial commit: finance-hub unified finance app
1 hour ago
.env.example
.env.example
Add Authentik auth, API key support, and remote MCP server
Add Authentik auth, API key support, and remote MCP server
2 minutes ago
.gitignore
.gitignore
Add Authentik auth, API key support, and remote MCP server
Add Authentik auth, API key support, and remote MCP server
2 minutes ago
docker-compose.yml
docker-compose.yml
Add Authentik auth, API key support, and remote MCP server
Add Authentik auth, API key support, and remote MCP server
2 minutes ago
README.md
README.md
Add README with project description, API reference, and usage guide
Add README with project description, API reference, and usage guide
1 hour ago
README.md Escape Edit File
README.md
README.md
Escape
Edit File
Finance Hub
Finance Hub
Unified personal finance tracker that consolidates DSK Bank SMS notifications and CSV statement exports into a single PostgreSQL database with a React review UI.
Replaces two separate tools:
payments-logger
— ingested DSK Bank SMS notifications
dsk-uploader
— parsed DSK Bank CSV exports and sent them to Notion
Features
Features
SMS ingest
— receives DSK Bank payment SMS via iOS Shortcuts / HTTP POST; parses amount, recipient, card, date, balance
CSV upload
— drag-and-drop DSK Bank account statement exports (BGN and EUR formats, cp1251 and UTF-8 encodings)
Deduplication
— exact
rawMessage
match prevents duplicate imports from re-uploads or re-runs of the reimport script
Auto-tagging
— new imports for a known recipient are automatically tagged based on tag history for that payee
Rule-based tagging
— CSV rows are auto-tagged by keyword rules (LIDL → Groceries, NETFLIX → Subscriptions, etc.)
Deduplication display
— same-day same-amount records from SMS and CSV are shown as a single "SMS + CSV" row in the UI
Notification forwarding
— sends payment summaries to a configurable notifier service (Viber, etc.)
Tag management
— create, colour-code, and remove tags on individual transactions
Settings
— column visibility, source row colouring, table density, mobile layout, hide balance-alert SMS
Auth
— delegated to Authentik via NPM reverse proxy header injection; no local user accounts
Tech Stack
Tech Stack
Layer
Technology
Backend
Node.js 20, Express, Prisma 5
Database
PostgreSQL 16
CSV parsing
csv-parse
,
iconv-lite
(cp1251 + UTF-8 BOM)
File upload
multer
(memory storage)
Frontend
React 18, Vite, Tailwind CSS, Lucide React
Auth
Authentik forward-auth via
X-authentik-username
header
Container
Docker Compose
Layer
Backend
Database
CSV parsing
File upload
Frontend
Auth
Container
Technology
Node.js 20, Express, Prisma 5
PostgreSQL 16
csv-parse
,
iconv-lite
(cp1251 + UTF-8 BOM)
multer
(memory storage)
React 18, Vite, Tailwind CSS, Lucide React
Authentik forward-auth via
X-authentik-username
header
Docker Compose
Quick Start
Quick Start
1. Clone and configure
1. Clone and configure
git clone [EMAIL]:lakylak/finance-hub.git
cd
finance-hub
cp .env.example .env
# Edit .env — set DB_PASSWORD and notifier settings
2. Start
2. Start
docker compose up -d --build
Services:
Service
Default port
Frontend
5175
Backend API
3001
Adminer (DB UI)
8092
Service
Frontend
Backend API
Adminer (DB UI)
Default port
5175
3001
8092
3. First run
3. First run
Prisma migrations run automatically on backend startup via
prisma migrate deploy
.
Environment variables
Environment variables
Variable
Required
Description
DB_PASSWORD
Yes
PostgreSQL password
NOTIFIER_URL
No
Base URL of the notifier service
NOTIFIER_CHANNEL
No
Channel to use (
viber
, etc.) Default:
viber
NOTIFY_DEFAULT_PHONE
No
Phone number for payment notifications
TZ
No
Timezone for SMS date parsing. Default:
Europe/Sofia
BACKEND_PORT
No
Backend listen port. Default:
3001
FRONTEND_PORT
No
Frontend listen port. Default:
5175
DEV_BYPASS_AUTH
No
Set
true
to skip Authentik header check during local dev
Variable
DB_PASSWORD
NOTIFIER_URL
NOTIFIER_CHANNEL
NOTIFY_DEFAULT_PHONE
TZ
BACKEND_PORT
FRONTEND_PORT
DEV_BYPASS_AUTH
Required
Yes
No
No
No
No
No
No
No
Description
PostgreSQL password
Base URL of the notifier service
Channel to use (
viber
, etc.) Default:
viber
Phone number for payment notifications
Timezone for SMS date parsing. Default:
Europe/Sofia
Backend listen port. Default:
3001
Frontend listen port. Default:
5175
Set
true
to skip Authentik header check during local dev
Authentication
Authentication
In production, route the frontend through
Nginx Proxy Manager
with an
Authentik forward-auth
provider. NPM injects
X-authentik-username
(and optionally
X-authentik-email
,
X-authentik-groups
) into every proxied request.
The backend reads these headers and rejects requests without them (unless
DEV_BYPASS_AUTH=true
).
The public endpoints below are exempt and require no authentication:
GET /api/health
POST /api/payments/ingest
Sign-out link:
/outpost.goauthentik.io/sign_out
API Reference
API Reference
Health
Health
GET /api/health
GET /api/health
Public. Returns service status and database connection info.
{
"status"
:
"ok"
,
"timestamp"
:
"2026-05-09T10:00:00.000Z"
,
"storage"
:
{
"type"
:
"PostgreSQL"
,
"host"
:
"db"
,
"database"
:
"finance_hub"
}
}
Payments (Transaction Imports)
Payments (Transaction Imports)
Base path:
/api/payments
All endpoints require authentication except
/ingest
.
POST /api/payments/ingest
POST /api/payments/ingest
Public.
Ingest a DSK Bank SMS notification or structured (Apple Wallet) payment.
Rate limited to
200 requests/minute
.
Returns
409
if the exact message was already imported.
SMS body:
{
"message"
:
"DSK Bank. Na 08/05/2026 v 19:32 sa plateni 67.81 EUR s karta 400915***4447 na POS s adres: LIDL BALGARIYA EOOD, SOFIYA, BGR. Nalichni: 2011.57 EUR."
}
Structured (Apple Wallet) body:
{
"ingestMode"
:
"apple_wallet"
,
"amount"
:
12.50
,
"recipient"
:
"Starbucks"
,
"type"
:
"WALLET"
,
"card"
:
"4444"
,
"date"
:
"2026-05-09T10:30:00Z"
,
"balance"
:
null
}
Response:
201 Created
— the created import record.
Duplicate:
409 Conflict
—
{ "error": "Already imported", "existing": { ... } }
GET /api/payments
GET /api/payments
List transaction imports with filtering, sorting, and pagination.
Query parameters:
Parameter
Type
Description
page
int
Page number. Default:
1
limit
int
Records per page, max 200. Default:
50
sortBy
string
Field to sort by:
date
,
amount
,
balance
,
recipient
,
type
,
source
,
createdAt
,
status
. Default:
createdAt
sortDir
string
asc
or
desc
. Default:
desc
status
string
Filter by status:
UNPROCESSED
,
SENT
,
SKIPPED
source
string
Filter by source:
INGEST
,
UPLOAD
type
string
Filter by transaction type (e.g.
POS
,
ATM
)
tag
string
Filter by tag name
recipient
string
Case-insensitive substring match on recipient
search
string
Case-insensitive search across
rawMessage
and
recipient
dateFrom
date
ISO date string — inclusive start of date range
dateTo
date
ISO date string — inclusive end of date range (interpreted as end of day)
hideBalanceAlerts
boolean
true
to exclude balance-notification SMS and records with no parsed amount
Parameter
page
limit
sortBy
sortDir
status
source
type
tag
recipient
search
dateFrom
dateTo
hideBalanceAlerts
Type
int
int
string
string
string
string
string
string
string
string
date
date
boolean
Description
Page number. Default:
1
Records per page, max 200. Default:
50
Field to sort by:
date
,
amount
,
balance
,
recipient
,
type
,
source
,...
|
14358
|
NULL
|
NULL
|
NULL
|
|
21383
|
936
|
4
|
2026-05-11T17:47:33.237810+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778521653237_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
Open sidebar
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....
|
[{"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,"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,"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":"Open sidebar","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"}]...
|
-8237378036658358958
|
1300413896619675165
|
click
|
hybrid
|
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
Open sidebar
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.
SlackFileEditViewGoHistoryWindowHelpDOCKER-rw-r--r---rw-r--r---rw-r--r---rw-r--r---rw-r--r---rw-r--r---rw-r--r---rw-r--r---W-r=-r---rw-r--r---rw-r--r--₴1DEV (docker)$2APP (-zsh)883-zsh1 lukasstaff562611May09:28soundcore AeroClip(input)_2026-05-11_6lukasstaff462011May09:29soundcore AeroCliplukasstaff881711(input)_2026-05-11_0May09:29soundcore AeroClip (input)_2026-05-11_0111lukasstaff581211May09:30soundcore AeroClip (input)_2026-05-11_0lukasstaff567111May09:30soundcore AeroCliplukasstaff796311May09:31(input)_2026-05-11_soundcore AeroClip(input)_2026-05-11_0lukasstaff661411May09:32soundcore AeroClip(input)_2026-05-11_/lukasstaff560611May09:32soundcore AeroClip(input)_2026-05-11_/lukasstaff639011Maylukasstaff603131109:33soundcore AeroClip (input)_2026-05-11_0May09:33soundcore AeroClip (input)_2026-05-11_01lukasstaff8843311May09:34soundcore AeroClip(input)_2026-05-11_9lukasstaff12524911May09:34soundcore AeroClip-rw-r--r---rw-r--r---rw-r--r---rw-r--r---rw-r--r---rw-r--r---rw-r--r---rw-r--r---rw-r--r--1lukasstaff10297511(input)_2026-05-11_May09:35soundcore AeroClip(input)_2026-05-11_lukasstaff2139911May09:35soundcore AeroClip(input)_2026-05-11_011lukasstaff3937911May09:36soundcore AeroCliplukasstaff995711May09:37(input)_2026-05-11_soundcore AeroClip(input)_2026-05-11_0lukasstaff8814811May09:37soundcore AeroClip(input)_2026-05-11_lukasstaff13584011May09:38soundcore AeroClip(input)_2026-05-11_1lukasstaff3477011 Maylukasstaff09:38soundcore AeroClip (input)_2026-05-11_(52737111lukasstaffMay09:39soundcore AeroClip (input)_2026-05-11_(7007011 May09:39soundcore AeroClip (input)_2026-05-11_0lukasstaff5062811May09:40soundcore AeroClip (input)_2026-05-11_(-rw-r--r---W-r--T---rw-r--r---rw-r--r---rw-r--r---rw-r--r---V=---s-rw-r--r---rw-r--r--lukasstaff7683811lukasMay09:40soundcore AeroClip (input)_2026-05-11_1staff66733 11 May09:41soundcore AeroClip (input)_2026-05-11_1lukasstaff7788711May09:41soundcore AeroClip1lukasstaff6392211May09:42(input)_2026-05-11_soundcore AeroClip(input)_2026-05-11_0lukasstaff1888411May09:42soundcore AeroClip(input)_2026-05-11_(11lukasstaff1394211May09:43soundcore AeroClip(input)_2026-05-11_/lukasstaff565011May09:44soundcore AeroCliplukasstaff462011May09:45(input)_2026-05-11_soundcore AeroClip (input)_2026-05-11.1lukasstaff685111May09:45soundcore AeroClip(input)_2026-05-11.lukasstaff110711 May09:45soundcore AeroClip-rw-r--r---V=---e-rw-r--r---Ver-=---rw-r--r---rw-r--r---V=--es-rw-r--r---rw-r--r--lukasstaff1780011May19:18(input)_2026-05-11soundcore AeroClip(input)_2026-05-11.lukasstaff1273211May19:19soundcore AeroClip(input)_2026-05-1111lukasstaff736111May19:19soundcore AeroCliplukasstaff1662211May19:20(input)_2026-05-11soundcore AeroClip (input)_2026-05-11lukasstaff15093611May19:21soundcore AeroClip (input)_2026-05-111lukasstaff13473211May19:21soundcore AeroClip(input)_2026-05-11lukasstaff2369011May19:22soundcore AeroCliplukasstaff(input)_2026-05-11.1665111May19:22soundcore AeroClip (input)_2026-05-11.1lukasstaff692211May19:23soundcore AeroClipinput)_2026-05-11.lukasstaff560311May19:23soundcore AeroClip-rw-r--r---rw-rlukasstaff4950911(input)_2026-05-11_May19:24soundcore AeroClip (input)_2026-05-11.1 lukasstaff34462 11May19:24soundcore AeroClip (input)_2026-05-11..ukas@Lukas-Kovaliks-MacBook-Pro-Jiminny'.screenpipe/data $ 11|||HomeDMsActivityFilesLaterMore-Jiminny ...# curiosity_lab# engineering# general# jiminny-bg# platform-tickets#product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...• Direct messagese. Aneliya Angelova% Galya DimitrovaLo Petko Kashinski8. Stefka Stoyanova€o Vasil VasilevNikolay Ivanov(3Aneliya Angelova, .... Stoyan Tanev. VesLukas Kovalik y…..l:: Apps$*) Jira CloudToast(abl100% C8• Mon 11 May 20:47:32Describe what you are looking for# releases8 22• MessagesC FilesBookmarks+9353b609 - JYToday~bee402b7- JY-20395 Stop fetching ALLheaders (including file) for email importd6a0fe5a - JY-20395 lintdaa0373e - JY-20395 lint fixesaf59d609 - JY-20395 Removed no longer usedmethodsShow morejiminny/app | Added by GitHubCircleCl APP 5:11 PMDeployment Successful!Project: appWhen:05/11/202614:11:35Tag:View JobCircleCl APP 5:35 PMDeployment Successful!Project: appWhen:05/11/202614:35:58Tag:View JobMessage #releases+Aa..•...
|
21381
|
NULL
|
NULL
|
NULL
|
|
6776
|
295
|
3
|
2026-05-08T07:14:11.255208+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-08/1778 /Users/lukas/.screenpipe/data/data/2026-05-08/1778224451255_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
True
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
9
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Pop out this video More screens are more fun. Play this video while you do other things.
Pop out this video
More screens are more fun. Play this video while you do other things.
Zoom in
Open in new window
Enter Full Screen
Pop out this video More screens are more fun. Play this video while you do other things.
Pop out this video
More screens are more fun. Play this video while you do other things.
Steliyan Georgiev
Pop out this video More screens are more fun. Play this video while you do other things.
Pop out this video
More screens are more fun. Play this video while you do other things.
Stefka Stoyanova
Pop out this video More screens are more fun. Play this video while you do other things.
Pop out this video
More screens are more fun. Play this video while you do other things.
Nikolay Yankov
User profile picture User profile picture 4 others
4 others
Pop out this video More screens are more fun. Play this video while you do other things.
Pop out this video
More screens are more fun. Play this video while you do other things.
Lukas Kovalik
Others might see more of your background. Click to view your full video.
10:14
AM
Daily - Platform
Daily - Platform
Audio settings
Turn on microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Galya Dimitrova joined...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"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.8411111,"width":0.033680554,"height":0.038333334},"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.8794444,"width":0.033680554,"height":0.03888889},"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.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.95666665,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Nikolay Yankov (Presenting)","depth":12,"bounds":{"left":0.07534722,"top":0.101111114,"width":0.124305554,"height":0.022222223},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov (Presenting)","depth":13,"bounds":{"left":0.07534722,"top":0.10222222,"width":0.124305554,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"People","depth":15,"bounds":{"left":0.88680553,"top":0.08944444,"width":0.04097222,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"9","depth":22,"bounds":{"left":0.9145833,"top":0.101111114,"width":0.0048611113,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Take notes with Gemini","depth":14,"bounds":{"left":0.93333334,"top":0.08944444,"width":0.025,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Take notes with Gemini","depth":17,"bounds":{"left":0.9361111,"top":0.101111114,"width":0.06388891,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini","depth":22,"bounds":{"left":0.96666664,"top":0.101111114,"width":0.028125,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Gemini","depth":21,"bounds":{"left":0.96458334,"top":0.090555556,"width":0.023611112,"height":0.037777778},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Pop out this video More screens are more fun. Play this video while you do other things.","depth":15,"bounds":{"left":0.5798611,"top":0.61,"width":0.14652778,"height":0.08888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pop out this video","depth":17,"bounds":{"left":0.7239583,"top":0.6244444,"width":0.08090278,"height":0.018888889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"More screens are more fun. Play this video while you do other things.","depth":16,"bounds":{"left":0.7017361,"top":0.6205556,"width":0.11076389,"height":0.05666667},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Zoom in","depth":13,"bounds":{"left":0.63090277,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open in new window","depth":13,"bounds":{"left":0.6642361,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Enter Full Screen","depth":13,"bounds":{"left":0.69756943,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Pop out this video More screens are more fun. Play this video while you do other things.","depth":15,"bounds":{"left":0.78541666,"top":0.27611113,"width":0.14652778,"height":0.07722222},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pop out this video","depth":17,"bounds":{"left":0.9295139,"top":0.2911111,"width":0.07048613,"height":0.017777778},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"More screens are more fun. Play this video while you do other things.","depth":16,"bounds":{"left":0.90729165,"top":0.28666666,"width":0.09270835,"height":0.045},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":17,"bounds":{"left":0.753125,"top":0.36277777,"width":0.090625,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pop out this video More screens are more fun. Play this video while you do other things.","depth":15,"bounds":{"left":0.90902776,"top":0.27611113,"width":0.090972245,"height":0.07722222},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pop out this video","depth":17,"bounds":{"left":1.0,"top":0.2911111,"width":-0.053125024,"height":0.017777778},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"More screens are more fun. Play this video while you do other things.","depth":16,"bounds":{"left":1.0,"top":0.28666666,"width":-0.030902743,"height":0.045},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":17,"bounds":{"left":0.87951386,"top":0.36277777,"width":0.088194445,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pop out this video More screens are more fun. Play this video while you do other things.","depth":15,"bounds":{"left":0.78541666,"top":0.5338889,"width":0.14652778,"height":0.07722222},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pop out this video","depth":17,"bounds":{"left":0.9295139,"top":0.54888886,"width":0.07048613,"height":0.017777778},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"More screens are more fun. Play this video while you do other things.","depth":16,"bounds":{"left":0.90729165,"top":0.54444444,"width":0.09270835,"height":0.045},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":17,"bounds":{"left":0.753125,"top":0.6205556,"width":0.07673611,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"User profile picture User profile picture 4 others","depth":11,"bounds":{"left":0.87118053,"top":0.40888888,"width":0.11805555,"height":0.24444444},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"4 others","depth":13,"bounds":{"left":0.90902776,"top":0.55722225,"width":0.04236111,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pop out this video More screens are more fun. Play this video while you do other things.","depth":15,"bounds":{"left":0.8840278,"top":0.7916667,"width":0.11597222,"height":0.07722222},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pop out this video","depth":17,"bounds":{"left":0.8107639,"top":0.8066667,"width":0.07569444,"height":0.017777778},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"More screens are more fun. Play this video while you do other things.","depth":16,"bounds":{"left":0.79131943,"top":0.80222225,"width":0.11736111,"height":0.045},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":17,"bounds":{"left":0.753125,"top":0.87833333,"width":0.06875,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Others might see more of your background. Click to view your full video.","depth":14,"bounds":{"left":0.96631944,"top":0.875,"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":"10:14","depth":12,"bounds":{"left":0.050347224,"top":0.9444444,"width":0.027083334,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AM","depth":12,"bounds":{"left":0.08090278,"top":0.9444444,"width":0.017708333,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Daily - Platform","depth":12,"bounds":{"left":0.11597222,"top":0.9111111,"width":0.08090278,"height":0.08888888},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily - Platform","depth":15,"bounds":{"left":0.11597222,"top":0.9444444,"width":0.08090278,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Audio settings","depth":13,"bounds":{"left":0.32118055,"top":0.9288889,"width":0.06111111,"height":0.053333335},"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":"Turn on microphone","depth":13,"bounds":{"left":0.34895834,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXButton","text":"Video settings","depth":13,"bounds":{"left":0.38784721,"top":0.9288889,"width":0.06111111,"height":0.053333335},"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":"Turn off camera","depth":13,"bounds":{"left":0.415625,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Nikolay Yankov is presenting","depth":12,"bounds":{"left":0.45451388,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Send a reaction","depth":12,"bounds":{"left":0.49895832,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn on captions","depth":13,"bounds":{"left":0.5434028,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Raise hand (ctrl + ⌘ + h)","depth":12,"bounds":{"left":0.58784723,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options","depth":12,"bounds":{"left":0.6322917,"top":0.9288889,"width":0.025,"height":0.053333335},"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":"Leave call","depth":12,"bounds":{"left":0.6628472,"top":0.9288889,"width":0.05,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Meeting details","depth":12,"bounds":{"left":0.89166665,"top":0.9288889,"width":0.033333335,"height":0.053333335},"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":"Chat with everyone","depth":12,"bounds":{"left":0.925,"top":0.9288889,"width":0.033333335,"height":0.053333335},"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":"Meeting tools","depth":12,"bounds":{"left":0.9583333,"top":0.9288889,"width":0.033333335,"height":0.053333335},"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":"Galya Dimitrova joined","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8236529777700556792
|
-6570497606676219116
|
idle
|
accessibility
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
9
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Pop out this video More screens are more fun. Play this video while you do other things.
Pop out this video
More screens are more fun. Play this video while you do other things.
Zoom in
Open in new window
Enter Full Screen
Pop out this video More screens are more fun. Play this video while you do other things.
Pop out this video
More screens are more fun. Play this video while you do other things.
Steliyan Georgiev
Pop out this video More screens are more fun. Play this video while you do other things.
Pop out this video
More screens are more fun. Play this video while you do other things.
Stefka Stoyanova
Pop out this video More screens are more fun. Play this video while you do other things.
Pop out this video
More screens are more fun. Play this video while you do other things.
Nikolay Yankov
User profile picture User profile picture 4 others
4 others
Pop out this video More screens are more fun. Play this video while you do other things.
Pop out this video
More screens are more fun. Play this video while you do other things.
Lukas Kovalik
Others might see more of your background. Click to view your full video.
10:14
AM
Daily - Platform
Daily - Platform
Audio settings
Turn on microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Galya Dimitrova joined...
|
6774
|
NULL
|
NULL
|
NULL
|
|
888
|
32
|
18
|
2026-05-07T07:39:05.942178+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778139545942_m2.jpg...
|
iTerm2
|
NULL
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Claude File EditVIewWindowHelp* Coffee and Claude Claude File EditVIewWindowHelp* Coffee and Claude time?How can I help you today?@ Write Q Learn<> Code Ö Life stuffSonnet 4.6 v• Claude's choicePlatform Sprint 3 Q2 - Platform Te)SevenShores|Hubspot\Exceptic XService-Desk - Queues - PlatformJy 20807 check various issues wital Sentry• Pull requests - jiminny/app1 Useroilot | Ask liminny Report Gen• New TabExplore08MonitorsSettingsSupport Daily - in 4h 21mnny.sentry.lo issues/0u/so00/4telIssues / APP-1EEDD: b2e90aбe7 hours ago |JSONJump to: HighlightsStack TraceTaasv Stack TraceDisplay~© Copy asIhere are z chained exceptions in this eventv SevenShores Hubsoot Excentions BadRequestClient error: *POST https://api.hubapi.com/crm/v3/objects/contact/search ( resulted in a '429loo Many kequests"status: error" message:You have reached your secondlvlimit." "errorivoe":"RATE UMi" "correlationid":019dttc4-4 (truncated...)mechanism generidCrashed in non-app:...endor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24 in Show 1 more frame_pp/Services/Crm/Hubspot/Paqination/HubspotPaginationService.php:163 in Jiminny Services Crm Hubs.-pp/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:51 in Jiminny|Services\Crm\Hubsp._/app/Services/Crm/Hubspot/Client.php:94 in Jiminny|Services\Crm\Hubspot\Client:getPaginatedDataIn App-op/Services/Crm/Hubspot/Service.php:1212 in Jiminny Services Crm Hubspot Service::Jiminny Services .Called from:endor/laravel/framework/src/llluminate/Cache/Repositorv.php:564 in Illuminate…app/Services/Crm/Hubspot/Service.php:1206 in JiminnyServices Crm Hubspot Service:matchByNameop/Services/Crm/CachedCrmServiceDecorator.oho:167 in Jiminnv|Services Crm.CachedCrmServiceDecor/app/Services/Crm/CrmActivityService.php:227 in Jiminny|Services\Crm\CrmActivityService:findCrmRecords-op/Services/Crm/CrmActivityService.oho:139 in Jiminny Services Crm CrmActivityService«updateParticio./app/Services/Crm/CrmActivityService.php:81 in Jiminny|Services\Crm\CrmActivityService:updateCrmData-pp/Jobs/Crm/MatchActivityCrmData.php:107 in Jiminny\Jobs\Crm\MatchActivityCrmData:Jiminny\Jobsl_Called from: .endor/laravel/framework/src/Illuminate/Database/Concerns/Man:/app/Jobs/Crm/MatchActivityCrmData.php:87 in Jiminny|Jobs\Crm\MatchActivityCrmData:handleCollod tram.ondor/lorovol/fromoworl/erc/llluminoto/Contoinor/PoundMothodnhn.2/dn.tttmlShow 14 more frames/app/Queue/Worker/Worker.php:71 in Jiminny\Queue\Worker\Worker:processCalled from: -endor/laravel/framework/src/Illuminate/Queue/Worker.php:435 in Illuminate\Qu..Chaw"r maretrs miod> GuzzleHttp\Exception\ClientExceptionv Trace PreviewView Full Trace100% L2Inu / May 10.39.0.ê Ask Seer % /• GitHub+ Jirav Activity8 Assignedby Lukas Kovalik to themselves.D Marked as Ongoingautomatically by Sentry# First Seen2 months agoo months agoo months agev PeopleCR participatingSSIRIPIN viewedSimilar IssuesMeraed ssues...
|
NULL
|
-8236468555930812525
|
NULL
|
visual_change
|
ocr
|
NULL
|
Claude File EditVIewWindowHelp* Coffee and Claude Claude File EditVIewWindowHelp* Coffee and Claude time?How can I help you today?@ Write Q Learn<> Code Ö Life stuffSonnet 4.6 v• Claude's choicePlatform Sprint 3 Q2 - Platform Te)SevenShores|Hubspot\Exceptic XService-Desk - Queues - PlatformJy 20807 check various issues wital Sentry• Pull requests - jiminny/app1 Useroilot | Ask liminny Report Gen• New TabExplore08MonitorsSettingsSupport Daily - in 4h 21mnny.sentry.lo issues/0u/so00/4telIssues / APP-1EEDD: b2e90aбe7 hours ago |JSONJump to: HighlightsStack TraceTaasv Stack TraceDisplay~© Copy asIhere are z chained exceptions in this eventv SevenShores Hubsoot Excentions BadRequestClient error: *POST https://api.hubapi.com/crm/v3/objects/contact/search ( resulted in a '429loo Many kequests"status: error" message:You have reached your secondlvlimit." "errorivoe":"RATE UMi" "correlationid":019dttc4-4 (truncated...)mechanism generidCrashed in non-app:...endor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24 in Show 1 more frame_pp/Services/Crm/Hubspot/Paqination/HubspotPaginationService.php:163 in Jiminny Services Crm Hubs.-pp/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:51 in Jiminny|Services\Crm\Hubsp._/app/Services/Crm/Hubspot/Client.php:94 in Jiminny|Services\Crm\Hubspot\Client:getPaginatedDataIn App-op/Services/Crm/Hubspot/Service.php:1212 in Jiminny Services Crm Hubspot Service::Jiminny Services .Called from:endor/laravel/framework/src/llluminate/Cache/Repositorv.php:564 in Illuminate…app/Services/Crm/Hubspot/Service.php:1206 in JiminnyServices Crm Hubspot Service:matchByNameop/Services/Crm/CachedCrmServiceDecorator.oho:167 in Jiminnv|Services Crm.CachedCrmServiceDecor/app/Services/Crm/CrmActivityService.php:227 in Jiminny|Services\Crm\CrmActivityService:findCrmRecords-op/Services/Crm/CrmActivityService.oho:139 in Jiminny Services Crm CrmActivityService«updateParticio./app/Services/Crm/CrmActivityService.php:81 in Jiminny|Services\Crm\CrmActivityService:updateCrmData-pp/Jobs/Crm/MatchActivityCrmData.php:107 in Jiminny\Jobs\Crm\MatchActivityCrmData:Jiminny\Jobsl_Called from: .endor/laravel/framework/src/Illuminate/Database/Concerns/Man:/app/Jobs/Crm/MatchActivityCrmData.php:87 in Jiminny|Jobs\Crm\MatchActivityCrmData:handleCollod tram.ondor/lorovol/fromoworl/erc/llluminoto/Contoinor/PoundMothodnhn.2/dn.tttmlShow 14 more frames/app/Queue/Worker/Worker.php:71 in Jiminny\Queue\Worker\Worker:processCalled from: -endor/laravel/framework/src/Illuminate/Queue/Worker.php:435 in Illuminate\Qu..Chaw"r maretrs miod> GuzzleHttp\Exception\ClientExceptionv Trace PreviewView Full Trace100% L2Inu / May 10.39.0.ê Ask Seer % /• GitHub+ Jirav Activity8 Assignedby Lukas Kovalik to themselves.D Marked as Ongoingautomatically by Sentry# First Seen2 months agoo months agoo months agev PeopleCR participatingSSIRIPIN viewedSimilar IssuesMeraed ssues...
|
886
|
NULL
|
NULL
|
NULL
|
|
25404
|
1066
|
26
|
2026-05-12T11:17:52.445295+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778584672445_m1.jpg...
|
Firefox
|
Platform Team - Backlog - Jira — Work
|
True
|
jiminny.atlassian.net/jira/software/c/projects/JY/ jiminny.atlassian.net/jira/software/c/projects/JY/boards/37/backlog?selectedIssue=JY-20773...
|
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
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
Close tab
[JY-20773] User Pilot not receiving events on report generated - Jira
[JY-20773] User Pilot not receiving events on report generated - 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
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
Space navigation
Space navigation
Panel
Panel
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...
|
[{"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":"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":"[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":"[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":"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":true},{"role":"AXStaticText","text":"Platform Team - Backlog - 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":"[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-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":"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":"AXStaticText","text":"Skip to:","depth":9,"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":"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":"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":"AXLink","text":"Panel","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Panel","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":11,"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":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rovo Ask Rovo","depth":12,"on_screen":false,"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":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Notifications","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Notifications","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Settings","depth":12,"on_screen":false,"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":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"lukas.kovalik@jiminny.com","depth":12,"on_screen":false,"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":false,"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}]...
|
-8235457268883868842
|
6492451801151402144
|
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
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
Close tab
[JY-20773] User Pilot not receiving events on report generated - Jira
[JY-20773] User Pilot not receiving events on report generated - 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
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
Space navigation
Space navigation
Panel
Panel
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...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
12833
|
NULL
|
0
|
2026-05-09T09:38:09.387385+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778319489387_m2.jpg...
|
Firefox
|
Select: payments - db - Adminer — Personal
|
True
|
http://192.168.0.242:8092/?pgsql=db&username=finan
|
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
Select: payments - db - Adminer
Select: payments - db - Adminer
Close tab
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
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
PostgreSQL
PostgreSQL
»
db
db
»
finance_hub
finance_hub
»
public
public
» Select: payments
Select: payments
Select: payments
Select data
Select data
Show structure
Show structure
Alter table
Alter table
New item
New item
Select
Select
Search
Search
Sort
Sort
Limit
50
Text length
100
Action
Select
SELECT
SELECT
*
FROM
"
payments
payments
"
LIMIT
50
(0.001 s)
Edit
Edit
Modify
Modify
id
id
raw_message
raw_message
date
date
type
type
card
card
recipient
recipient
amount
amount
currency
currency
balance
balance
source
source
status
status
notified_at
notified_at
notify_phone
notify_phone
debit_bgn
debit_bgn
credit_bgn
credit_bgn
transaction_type
transaction_type
payer_account
payer_account
created_at
created_at
updated_at
updated_at
edit
edit
1
DSK Bank. Na 08/05/2026 v 10:00 sa iztegleni 200.00 EUR s karta 400915***4447 ot ATM s adres: DSK AT
…
2026-05-08 07:00:00
ATM
400915***4447
DSK ATM, SOFIA, BG
200
EUR
1050
INGEST
UNPROCESSED
NULL
[PHONE]
NULL
NULL
NULL
NULL
2026-05-09 06:44:52.867
2026-05-09 06:44:52.867
edit
edit
2
DSK Bank. Na 08/05/2026 v 19:32 sa plateni 67.81 EUR s karta 400915***4447 na POS s adres: LIDL BALG
…
2026-05-08 16:32:00
POS
400915***4447
LIDL BALGARIYA EOOD, SOFIYA, BGR
67.81
EUR
2011.57
INGEST
UNPROCESSED
NULL
NULL
NULL
NULL
NULL
NULL
2026-05-09 06:59:18.596
2026-05-09 06:59:18.596
edit
edit
9
Date: 08.05.2026 | Debit: 5.02 EUR
2026-05-08 00:00:00
NULL
400915xxxxxx4447
NULL
5.02
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
5.02
NULL
NULL
NULL
2026-05-09 09:29:57.778
2026-05-09 09:29:57.778
edit
edit
10
Date: 08.05.2026 | Debit: 15.46 EUR
2026-05-08 00:00:00
NULL
400915xxxxxx4447
NULL
15.46
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
15.46
NULL
NULL
NULL
2026-05-09 09:29:57.79
2026-05-09 09:29:57.79
edit
edit
11
Date: 08.05.2026 | Debit: 9.04 EUR
2026-05-08 00:00:00
NULL
400915xxxxxx4447
NULL
9.04
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
9.04
NULL
NULL
NULL
2026-05-09 09:29:57.798
2026-05-09 09:29:57.798
edit
edit
12
Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR | Debit:
…
2026-05-08 16:32:00
NULL
400915xxxxxx4447
BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR
67.81
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
67.81
NULL
КАРТОВА ОПЕРАЦИЯ
NULL
2026-05-09 09:29:57.81
2026-05-09 09:29:57.81
edit
edit
13
Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIA CBA EKO MARKET | Debit: 5.51 EUR
2026-05-07 06:02:00
NULL
400915xxxxxx4447
BGR SOFIA CBA EKO MARKET
5.51
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
5.51
NULL
КАРТОВА ОПЕРАЦИЯ
NULL
2026-05-09 09:29:57.827
2026-05-09 09:29:57.827
edit
edit
14
Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: POL BALICE Lagardere Travel R KR3 | Debit: 5.49 E
…
2026-05-06 10:16:00
NULL
400915xxxxxx4447
POL BALICE Lagardere Travel R KR3
5.49
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
5.49
NULL
КАРТОВА ОПЕРАЦИЯ
NULL
2026-05-09 09:29:57.84
2026-05-09 09:29:57.84
edit
edit
15
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ | Debit: 17.93 EUR
2026-05-04 00:00:00
NULL
NULL
КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ
17.93
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
17.93
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.861
2026-05-09 09:29:57.861
edit
edit
16
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 8.44 EUR
2026-05-04 00:00:00
NULL
NULL
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
8.44
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
8.44
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.876
2026-05-09 09:29:57.876
edit
edit
17
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit:
…
2026-05-04 00:00:00
NULL
NULL
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
47.63
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
47.63
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.891
2026-05-09 09:29:57.891
edit
edit
18
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit:
…
2026-05-04 00:00:00
NULL
NULL
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
0.09
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
0.09
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.906
2026-05-09 09:29:57.906
edit
edit
19
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 29.54 EUR
2026-05-04 00:00:00
NULL
NULL
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
29.54
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
29.54
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.919
2026-05-09 09:29:57.919
edit
edit
20
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА | Debit:
…
2026-05-04 00:00:00
NULL
NULL
ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА
14.27
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
14.27
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.934
2026-05-09 09:29:57.934
edit
edit
21
Date: 04.05.2026 | Type: ПРЕВОД SEPA | Payee: ЧЦДГ МИЛА | Debit: 460 EUR
2026-05-04 00:00:00
NULL
NULL
ЧЦДГ МИЛА
460
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
460
NULL
ПРЕВОД SEPA
[IBAN]
2026-05-09 09:29:57.945
2026-05-09 09:29:57.945
edit
edit
22
Date: 30.04.2026 | Debit: 10.22 EUR
2026-04-30 00:00:00
NULL
NULL
NULL
10.22
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
10.22
NULL
NULL
[CREDIT_CARD]
2026-05-09 09:29:57.955
2026-05-09 09:29:57.955
edit
edit
23
Date: 30.04.2026 | Type: ВХОДЯЩ ПАРИЧЕН ПРЕВОД | Payee: ВЕДА ПЕЙРОЛ ООД | Credit: 4325.26 EUR
2026-04-30 00:00:00
NULL...
|
[{"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":false},{"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":"AXRadioButton","text":"Select: payments - 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":true},{"role":"AXStaticText","text":"Select: payments - db - Adminer","depth":5,"bounds":{"left":0.013297873,"top":0.5865922,"width":0.05651596,"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.5826017,"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":"Електронно банкиране ДСК Директ от Банка ДСК","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":"AXLink","text":"PostgreSQL","depth":8,"bounds":{"left":0.013630319,"top":0.055067837,"width":0.027593086,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"PostgreSQL","depth":9,"bounds":{"left":0.013630319,"top":0.055067837,"width":0.027593086,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"»","depth":8,"bounds":{"left":0.041223403,"top":0.055067837,"width":0.006482713,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"db","depth":8,"bounds":{"left":0.047706116,"top":0.055067837,"width":0.005984043,"height":0.014365523},"on_screen":true,"help_text":"Alt+Shift+1","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"db","depth":9,"bounds":{"left":0.047706116,"top":0.055067837,"width":0.005984043,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"»","depth":8,"bounds":{"left":0.053690158,"top":0.055067837,"width":0.0063164895,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"finance_hub","depth":8,"bounds":{"left":0.06000665,"top":0.055067837,"width":0.029421542,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"finance_hub","depth":9,"bounds":{"left":0.06000665,"top":0.055067837,"width":0.029421542,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"»","depth":8,"bounds":{"left":0.089428194,"top":0.055067837,"width":0.006482713,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"public","depth":8,"bounds":{"left":0.09591091,"top":0.055067837,"width":0.01412899,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"public","depth":9,"bounds":{"left":0.09591091,"top":0.055067837,"width":0.01412899,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"» Select: payments","depth":8,"bounds":{"left":0.1100399,"top":0.055067837,"width":0.048537236,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Select: payments","depth":7,"bounds":{"left":0.00880984,"top":0.0830008,"width":0.99119014,"height":0.04988029},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select: payments","depth":8,"bounds":{"left":0.015957447,"top":0.096568234,"width":0.0631649,"height":0.021548284},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Select data","depth":8,"bounds":{"left":0.014793883,"top":0.14884278,"width":0.029920213,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select data","depth":9,"bounds":{"left":0.014793883,"top":0.14884278,"width":0.029920213,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Show structure","depth":8,"bounds":{"left":0.053025264,"top":0.14884278,"width":0.03656915,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show structure","depth":9,"bounds":{"left":0.053025264,"top":0.14884278,"width":0.03656915,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Alter table","depth":8,"bounds":{"left":0.09790558,"top":0.14884278,"width":0.024933511,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Alter table","depth":9,"bounds":{"left":0.09790558,"top":0.14884278,"width":0.024933511,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New item","depth":8,"bounds":{"left":0.13131648,"top":0.14884278,"width":0.022606382,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New item","depth":9,"bounds":{"left":0.13131648,"top":0.14884278,"width":0.022606382,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Select","depth":10,"bounds":{"left":0.019614361,"top":0.17238627,"width":0.01462766,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select","depth":11,"bounds":{"left":0.019614361,"top":0.17238627,"width":0.01462766,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Search","depth":10,"bounds":{"left":0.048038565,"top":0.17238627,"width":0.016456118,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search","depth":11,"bounds":{"left":0.048038565,"top":0.17238627,"width":0.016456118,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sort","depth":10,"bounds":{"left":0.07829122,"top":0.17238627,"width":0.010139627,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sort","depth":11,"bounds":{"left":0.07829122,"top":0.17238627,"width":0.010139627,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Limit","depth":10,"bounds":{"left":0.10206117,"top":0.17238627,"width":0.011968086,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"50","depth":11,"bounds":{"left":0.102726065,"top":0.19473264,"width":0.005485372,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Text length","depth":10,"bounds":{"left":0.13081782,"top":0.17238627,"width":0.026761968,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"100","depth":11,"bounds":{"left":0.1314827,"top":0.19473264,"width":0.0076462766,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Action","depth":10,"bounds":{"left":0.17137633,"top":0.17238627,"width":0.014960106,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Select","depth":10,"bounds":{"left":0.17071144,"top":0.19233839,"width":0.016954787,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"SELECT","depth":9,"bounds":{"left":0.015458777,"top":0.22785315,"width":0.015458777,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SELECT","depth":10,"bounds":{"left":0.015458777,"top":0.22785315,"width":0.015458777,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":9,"bounds":{"left":0.030917553,"top":0.22785315,"width":0.0076462766,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FROM","depth":10,"bounds":{"left":0.03856383,"top":0.22785315,"width":0.010305851,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"","depth":9,"bounds":{"left":0.051529255,"top":0.22785315,"width":0.002493351,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"payments","depth":9,"bounds":{"left":0.054022606,"top":0.22785315,"width":0.020611702,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"payments","depth":10,"bounds":{"left":0.054022606,"top":0.22785315,"width":0.020611702,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"","depth":9,"bounds":{"left":0.074634306,"top":0.22785315,"width":0.0026595744,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"LIMIT","depth":10,"bounds":{"left":0.07978723,"top":0.22785315,"width":0.012965426,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"50","depth":9,"bounds":{"left":0.09524601,"top":0.22785315,"width":0.0051529254,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(0.001 s)","depth":8,"bounds":{"left":0.102726065,"top":0.22905028,"width":0.015791224,"height":0.0103751},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Edit","depth":8,"bounds":{"left":0.12017952,"top":0.22585794,"width":0.00930851,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Edit","depth":9,"bounds":{"left":0.12017952,"top":0.22585794,"width":0.00930851,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Modify","depth":12,"bounds":{"left":0.024933511,"top":0.25339186,"width":0.01412899,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Modify","depth":13,"bounds":{"left":0.024933511,"top":0.25339186,"width":0.01412899,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"id","depth":12,"bounds":{"left":0.04288564,"top":0.254988,"width":0.004488032,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"id","depth":14,"bounds":{"left":0.04288564,"top":0.254988,"width":0.004488032,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"raw_message","depth":12,"bounds":{"left":0.16638963,"top":0.254988,"width":0.03357713,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"raw_message","depth":14,"bounds":{"left":0.16638963,"top":0.254988,"width":0.03357713,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"date","depth":12,"bounds":{"left":0.33676863,"top":0.254988,"width":0.010638298,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"date","depth":14,"bounds":{"left":0.33676863,"top":0.254988,"width":0.010638298,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"type","depth":12,"bounds":{"left":0.3698471,"top":0.254988,"width":0.010638298,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"type","depth":14,"bounds":{"left":0.3698471,"top":0.254988,"width":0.010638298,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"card","depth":12,"bounds":{"left":0.40026596,"top":0.254988,"width":0.010638298,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"card","depth":14,"bounds":{"left":0.40026596,"top":0.254988,"width":0.010638298,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"recipient","depth":12,"bounds":{"left":0.47755983,"top":0.254988,"width":0.021276595,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"recipient","depth":14,"bounds":{"left":0.47755983,"top":0.254988,"width":0.021276595,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"amount","depth":12,"bounds":{"left":0.5503657,"top":0.254988,"width":0.018450798,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"amount","depth":14,"bounds":{"left":0.5503657,"top":0.254988,"width":0.018450798,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"currency","depth":12,"bounds":{"left":0.5734708,"top":0.254988,"width":0.021276595,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"currency","depth":14,"bounds":{"left":0.5734708,"top":0.254988,"width":0.021276595,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"balance","depth":12,"bounds":{"left":0.5994016,"top":0.254988,"width":0.01861702,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"balance","depth":14,"bounds":{"left":0.5994016,"top":0.254988,"width":0.01861702,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"source","depth":12,"bounds":{"left":0.62267286,"top":0.254988,"width":0.016123671,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"source","depth":14,"bounds":{"left":0.62267286,"top":0.254988,"width":0.016123671,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"status","depth":12,"bounds":{"left":0.6515958,"top":0.254988,"width":0.014960106,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"status","depth":14,"bounds":{"left":0.6515958,"top":0.254988,"width":0.014960106,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"notified_at","depth":12,"bounds":{"left":0.679355,"top":0.254988,"width":0.026595745,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"notified_at","depth":14,"bounds":{"left":0.679355,"top":0.254988,"width":0.026595745,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"notify_phone","depth":12,"bounds":{"left":0.71193486,"top":0.254988,"width":0.032081116,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"notify_phone","depth":14,"bounds":{"left":0.71193486,"top":0.254988,"width":0.032081116,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"debit_bgn","depth":12,"bounds":{"left":0.75,"top":0.254988,"width":0.02443484,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"debit_bgn","depth":14,"bounds":{"left":0.75,"top":0.254988,"width":0.02443484,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"credit_bgn","depth":12,"bounds":{"left":0.7790891,"top":0.254988,"width":0.026097074,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"credit_bgn","depth":14,"bounds":{"left":0.7790891,"top":0.254988,"width":0.026097074,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"transaction_type","depth":12,"bounds":{"left":0.8238032,"top":0.254988,"width":0.041223403,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"transaction_type","depth":14,"bounds":{"left":0.8238032,"top":0.254988,"width":0.041223403,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"payer_account","depth":12,"bounds":{"left":0.8962766,"top":0.254988,"width":0.035738032,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"payer_account","depth":14,"bounds":{"left":0.8962766,"top":0.254988,"width":0.035738032,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"created_at","depth":12,"bounds":{"left":0.96392953,"top":0.254988,"width":0.026263298,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"created_at","depth":14,"bounds":{"left":0.96392953,"top":0.254988,"width":0.026263298,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"updated_at","depth":12,"bounds":{"left":1.0,"top":0.254988,"width":-0.023603678,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"updated_at","depth":14,"bounds":{"left":1.0,"top":0.254988,"width":-0.023603678,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.024933511,"top":0.2745411,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.024933511,"top":0.2745411,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":11,"bounds":{"left":0.04537899,"top":0.27573824,"width":0.0028257978,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DSK Bank. Na 08/05/2026 v 10:00 sa iztegleni 200.00 EUR s karta 400915***4447 ot ATM s adres: DSK AT","depth":11,"bounds":{"left":0.051030584,"top":0.27573824,"width":0.23636968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"…","depth":11,"bounds":{"left":0.28740028,"top":0.27573824,"width":0.0034906915,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-08 07:00:00","depth":11,"bounds":{"left":0.31831783,"top":0.27573824,"width":0.047706116,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ATM","depth":11,"bounds":{"left":0.36884972,"top":0.27573824,"width":0.008976064,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"400915***4447","depth":11,"bounds":{"left":0.38414228,"top":0.27573824,"width":0.035738032,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DSK ATM, SOFIA, BG","depth":11,"bounds":{"left":0.42985374,"top":0.27573824,"width":0.045711435,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":11,"bounds":{"left":0.56150264,"top":0.27573824,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.57263964,"top":0.27573824,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1050","depth":11,"bounds":{"left":0.607879,"top":0.27573824,"width":0.010970744,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"INGEST","depth":11,"bounds":{"left":0.6218417,"top":0.27573824,"width":0.01662234,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.64261967,"top":0.27573824,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.67852396,"top":0.27573824,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"+359888123456","depth":11,"bounds":{"left":0.70977396,"top":0.27573824,"width":0.036402926,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.764129,"top":0.27573824,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.79488033,"top":0.27573824,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8090093,"top":0.27573824,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8828125,"top":0.27573824,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 06:44:52.867","depth":11,"bounds":{"left":0.94830453,"top":0.27573824,"width":0.051695466,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 06:44:52.867","depth":11,"bounds":{"left":1.0,"top":0.27573824,"width":-0.008809805,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.024933511,"top":0.2952913,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.024933511,"top":0.2952913,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2","depth":11,"bounds":{"left":0.04537899,"top":0.29688746,"width":0.0028257978,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DSK Bank. Na 08/05/2026 v 19:32 sa plateni 67.81 EUR s karta 400915***4447 na POS s adres: LIDL BALG","depth":11,"bounds":{"left":0.051030584,"top":0.29688746,"width":0.23803191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"…","depth":11,"bounds":{"left":0.2890625,"top":0.29688746,"width":0.003656915,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-08 16:32:00","depth":11,"bounds":{"left":0.31831783,"top":0.29688746,"width":0.047706116,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"POS","depth":11,"bounds":{"left":0.36884972,"top":0.29688746,"width":0.008976064,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"400915***4447","depth":11,"bounds":{"left":0.38414228,"top":0.29688746,"width":0.035738032,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"LIDL BALGARIYA EOOD, SOFIYA, BGR","depth":11,"bounds":{"left":0.42985374,"top":0.29688746,"width":0.08194814,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67.81","depth":11,"bounds":{"left":0.5571808,"top":0.29688746,"width":0.012466756,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.57263964,"top":0.29688746,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2011.57","depth":11,"bounds":{"left":0.6008976,"top":0.29688746,"width":0.017952127,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"INGEST","depth":11,"bounds":{"left":0.6218417,"top":0.29688746,"width":0.01662234,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.64261967,"top":0.29688746,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.67852396,"top":0.29688746,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.70977396,"top":0.29688746,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.764129,"top":0.29688746,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.79488033,"top":0.29688746,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8090093,"top":0.29688746,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8828125,"top":0.29688746,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 06:59:18.596","depth":11,"bounds":{"left":0.94830453,"top":0.29688746,"width":0.051695466,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 06:59:18.596","depth":11,"bounds":{"left":1.0,"top":0.29688746,"width":-0.008809805,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.024933511,"top":0.31644055,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.024933511,"top":0.31644055,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9","depth":11,"bounds":{"left":0.04537899,"top":0.31763768,"width":0.0028257978,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 08.05.2026 | Debit: 5.02 EUR","depth":11,"bounds":{"left":0.051030584,"top":0.31763768,"width":0.07895612,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-08 00:00:00","depth":11,"bounds":{"left":0.31831783,"top":0.31763768,"width":0.047706116,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.36884972,"top":0.31763768,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"400915xxxxxx4447","depth":11,"bounds":{"left":0.38414228,"top":0.31763768,"width":0.042719416,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.42985374,"top":0.31763768,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.02","depth":11,"bounds":{"left":0.5600067,"top":0.31763768,"width":0.009640957,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.57263964,"top":0.31763768,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.60771275,"top":0.31763768,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6218417,"top":0.31763768,"width":0.017785905,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.64261967,"top":0.31763768,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.67852396,"top":0.31763768,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.70977396,"top":0.31763768,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.02","depth":11,"bounds":{"left":0.76545876,"top":0.31763768,"width":0.009807181,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.79488033,"top":0.31763768,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8090093,"top":0.31763768,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8828125,"top":0.31763768,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.778","depth":11,"bounds":{"left":0.94830453,"top":0.31763768,"width":0.051695466,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.778","depth":11,"bounds":{"left":1.0,"top":0.31763768,"width":-0.008809805,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.024933511,"top":0.33719075,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.024933511,"top":0.33719075,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10","depth":11,"bounds":{"left":0.042719416,"top":0.33838788,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 08.05.2026 | Debit: 15.46 EUR","depth":11,"bounds":{"left":0.051030584,"top":0.33838788,"width":0.081615694,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-08 00:00:00","depth":11,"bounds":{"left":0.31831783,"top":0.33838788,"width":0.047706116,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.36884972,"top":0.33838788,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"400915xxxxxx4447","depth":11,"bounds":{"left":0.38414228,"top":0.33838788,"width":0.042719416,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.42985374,"top":0.33838788,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15.46","depth":11,"bounds":{"left":0.5571808,"top":0.33838788,"width":0.012466756,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.57263964,"top":0.33838788,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.60771275,"top":0.33838788,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6218417,"top":0.33838788,"width":0.017785905,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.64261967,"top":0.33838788,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.67852396,"top":0.33838788,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.70977396,"top":0.33838788,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15.46","depth":11,"bounds":{"left":0.7627992,"top":0.33838788,"width":0.012466756,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.79488033,"top":0.33838788,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8090093,"top":0.33838788,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8828125,"top":0.33838788,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.79","depth":11,"bounds":{"left":0.94830453,"top":0.33838788,"width":0.051695466,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.79","depth":11,"bounds":{"left":1.0,"top":0.33838788,"width":-0.008809805,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.024933511,"top":0.35794094,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.024933511,"top":0.35794094,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11","depth":11,"bounds":{"left":0.042719416,"top":0.35953712,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 08.05.2026 | Debit: 9.04 EUR","depth":11,"bounds":{"left":0.051030584,"top":0.35953712,"width":0.07895612,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-08 00:00:00","depth":11,"bounds":{"left":0.31831783,"top":0.35953712,"width":0.047706116,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.36884972,"top":0.35953712,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"400915xxxxxx4447","depth":11,"bounds":{"left":0.38414228,"top":0.35953712,"width":0.042719416,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.42985374,"top":0.35953712,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9.04","depth":11,"bounds":{"left":0.5600067,"top":0.35953712,"width":0.009640957,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.57263964,"top":0.35953712,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.60771275,"top":0.35953712,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6218417,"top":0.35953712,"width":0.017785905,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.64261967,"top":0.35953712,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.67852396,"top":0.35953712,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.70977396,"top":0.35953712,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9.04","depth":11,"bounds":{"left":0.76545876,"top":0.35953712,"width":0.009807181,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.79488033,"top":0.35953712,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8090093,"top":0.35953712,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8828125,"top":0.35953712,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.798","depth":11,"bounds":{"left":0.94830453,"top":0.35953712,"width":0.051695466,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.798","depth":11,"bounds":{"left":1.0,"top":0.35953712,"width":-0.008809805,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.024933511,"top":0.3790902,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.024933511,"top":0.3790902,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12","depth":11,"bounds":{"left":0.042719416,"top":0.38028732,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR | Debit:","depth":11,"bounds":{"left":0.051030584,"top":0.38028732,"width":0.24800532,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"…","depth":11,"bounds":{"left":0.2990359,"top":0.38028732,"width":0.0034906915,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-08 16:32:00","depth":11,"bounds":{"left":0.31831783,"top":0.38028732,"width":0.047706116,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.36884972,"top":0.38028732,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"400915xxxxxx4447","depth":11,"bounds":{"left":0.38414228,"top":0.38028732,"width":0.042719416,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR","depth":11,"bounds":{"left":0.42985374,"top":0.38028732,"width":0.10322473,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67.81","depth":11,"bounds":{"left":0.5571808,"top":0.38028732,"width":0.012466756,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.57263964,"top":0.38028732,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.60771275,"top":0.38028732,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6218417,"top":0.38028732,"width":0.017785905,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.64261967,"top":0.38028732,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.67852396,"top":0.38028732,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.70977396,"top":0.38028732,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67.81","depth":11,"bounds":{"left":0.7627992,"top":0.38028732,"width":0.012466756,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.79488033,"top":0.38028732,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КАРТОВА ОПЕРАЦИЯ","depth":11,"bounds":{"left":0.8090093,"top":0.38028732,"width":0.04637633,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8828125,"top":0.38028732,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.81","depth":11,"bounds":{"left":0.94830453,"top":0.38028732,"width":0.051695466,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.81","depth":11,"bounds":{"left":1.0,"top":0.38028732,"width":-0.008809805,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.024933511,"top":0.39984038,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.024933511,"top":0.39984038,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13","depth":11,"bounds":{"left":0.042719416,"top":0.40143654,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIA CBA EKO MARKET | Debit: 5.51 EUR","depth":11,"bounds":{"left":0.051030584,"top":0.40143654,"width":0.22988696,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-07 06:02:00","depth":11,"bounds":{"left":0.31831783,"top":0.40143654,"width":0.047706116,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.36884972,"top":0.40143654,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"400915xxxxxx4447","depth":11,"bounds":{"left":0.38414228,"top":0.40143654,"width":0.042719416,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BGR SOFIA CBA EKO MARKET","depth":11,"bounds":{"left":0.42985374,"top":0.40143654,"width":0.06482713,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.51","depth":11,"bounds":{"left":0.5600067,"top":0.40143654,"width":0.009640957,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.57263964,"top":0.40143654,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.60771275,"top":0.40143654,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6218417,"top":0.40143654,"width":0.017785905,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.64261967,"top":0.40143654,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.67852396,"top":0.40143654,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.70977396,"top":0.40143654,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.51","depth":11,"bounds":{"left":0.76545876,"top":0.40143654,"width":0.009807181,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.79488033,"top":0.40143654,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КАРТОВА ОПЕРАЦИЯ","depth":11,"bounds":{"left":0.8090093,"top":0.40143654,"width":0.04637633,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8828125,"top":0.40143654,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.827","depth":11,"bounds":{"left":0.94830453,"top":0.40143654,"width":0.051695466,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.827","depth":11,"bounds":{"left":1.0,"top":0.40143654,"width":-0.008809805,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.024933511,"top":0.42098963,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.024933511,"top":0.42098963,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"14","depth":11,"bounds":{"left":0.042719416,"top":0.42218676,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: POL BALICE Lagardere Travel R KR3 | Debit: 5.49 E","depth":11,"bounds":{"left":0.051030584,"top":0.42218676,"width":0.23703457,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"…","depth":11,"bounds":{"left":0.28806517,"top":0.42218676,"width":0.0034906915,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-06 10:16:00","depth":11,"bounds":{"left":0.31831783,"top":0.42218676,"width":0.047706116,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.36884972,"top":0.42218676,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"400915xxxxxx4447","depth":11,"bounds":{"left":0.38414228,"top":0.42218676,"width":0.042719416,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"POL BALICE Lagardere Travel R KR3","depth":11,"bounds":{"left":0.42985374,"top":0.42218676,"width":0.078125,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.49","depth":11,"bounds":{"left":0.5600067,"top":0.42218676,"width":0.009640957,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.57263964,"top":0.42218676,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.60771275,"top":0.42218676,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6218417,"top":0.42218676,"width":0.017785905,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.64261967,"top":0.42218676,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.67852396,"top":0.42218676,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.70977396,"top":0.42218676,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.49","depth":11,"bounds":{"left":0.76545876,"top":0.42218676,"width":0.009807181,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.79488033,"top":0.42218676,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КАРТОВА ОПЕРАЦИЯ","depth":11,"bounds":{"left":0.8090093,"top":0.42218676,"width":0.04637633,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8828125,"top":0.42218676,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.84","depth":11,"bounds":{"left":0.94830453,"top":0.42218676,"width":0.051695466,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.84","depth":11,"bounds":{"left":1.0,"top":0.42218676,"width":-0.008809805,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.024933511,"top":0.44173983,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.024933511,"top":0.44173983,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15","depth":11,"bounds":{"left":0.042719416,"top":0.44293696,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ | Debit: 17.93 EUR","depth":11,"bounds":{"left":0.051030584,"top":0.44293696,"width":0.24850398,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-04 00:00:00","depth":11,"bounds":{"left":0.31831783,"top":0.44293696,"width":0.047706116,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.36884972,"top":0.44293696,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38414228,"top":0.44293696,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ","depth":11,"bounds":{"left":0.42985374,"top":0.44293696,"width":0.079953454,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17.93","depth":11,"bounds":{"left":0.5571808,"top":0.44293696,"width":0.012466756,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.57263964,"top":0.44293696,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.60771275,"top":0.44293696,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6218417,"top":0.44293696,"width":0.017785905,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.64261967,"top":0.44293696,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.67852396,"top":0.44293696,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.70977396,"top":0.44293696,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17.93","depth":11,"bounds":{"left":0.7627992,"top":0.44293696,"width":0.012466756,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.79488033,"top":0.44293696,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КОМУНАЛНИ УСЛУГИ","depth":11,"bounds":{"left":0.8090093,"top":0.44293696,"width":0.04720745,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG91STSA93000004594021","depth":11,"bounds":{"left":0.8828125,"top":0.44293696,"width":0.061668884,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.861","depth":11,"bounds":{"left":0.94830453,"top":0.44293696,"width":0.051695466,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.861","depth":11,"bounds":{"left":1.0,"top":0.44293696,"width":-0.008809805,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.024933511,"top":0.46249002,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.024933511,"top":0.46249002,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"16","depth":11,"bounds":{"left":0.042719416,"top":0.4640862,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 8.44 EUR","depth":11,"bounds":{"left":0.051030584,"top":0.4640862,"width":0.23404256,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-04 00:00:00","depth":11,"bounds":{"left":0.31831783,"top":0.4640862,"width":0.047706116,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.36884972,"top":0.4640862,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38414228,"top":0.4640862,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"С0ФИЙСКА ВОДА ДСК ДИРЕКТ","depth":11,"bounds":{"left":0.42985374,"top":0.4640862,"width":0.068317816,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8.44","depth":11,"bounds":{"left":0.5600067,"top":0.4640862,"width":0.009640957,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.57263964,"top":0.4640862,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.60771275,"top":0.4640862,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6218417,"top":0.4640862,"width":0.017785905,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.64261967,"top":0.4640862,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.67852396,"top":0.4640862,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.70977396,"top":0.4640862,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8.44","depth":11,"bounds":{"left":0.76545876,"top":0.4640862,"width":0.009807181,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.79488033,"top":0.4640862,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КОМУНАЛНИ УСЛУГИ","depth":11,"bounds":{"left":0.8090093,"top":0.4640862,"width":0.04720745,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG03STSA93000045940400","depth":11,"bounds":{"left":0.8828125,"top":0.4640862,"width":0.061668884,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.876","depth":11,"bounds":{"left":0.94830453,"top":0.4640862,"width":0.051695466,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.876","depth":11,"bounds":{"left":1.0,"top":0.4640862,"width":-0.008809805,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.024933511,"top":0.48363927,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.024933511,"top":0.48363927,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17","depth":11,"bounds":{"left":0.042719416,"top":0.4848364,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit:","depth":11,"bounds":{"left":0.051030584,"top":0.4848364,"width":0.26080453,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"…","depth":11,"bounds":{"left":0.3118351,"top":0.4848364,"width":0.0034906915,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-04 00:00:00","depth":11,"bounds":{"left":0.31831783,"top":0.4848364,"width":0.047706116,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.36884972,"top":0.4848364,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38414228,"top":0.4848364,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ","depth":11,"bounds":{"left":0.42985374,"top":0.4848364,"width":0.11668883,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"47.63","depth":11,"bounds":{"left":0.5571808,"top":0.4848364,"width":0.012466756,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.57263964,"top":0.4848364,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.60771275,"top":0.4848364,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6218417,"top":0.4848364,"width":0.017785905,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.64261967,"top":0.4848364,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.67852396,"top":0.4848364,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.70977396,"top":0.4848364,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"47.63","depth":11,"bounds":{"left":0.7627992,"top":0.4848364,"width":0.012466756,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.79488033,"top":0.4848364,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КОМУНАЛНИ УСЛУГИ","depth":11,"bounds":{"left":0.8090093,"top":0.4848364,"width":0.04720745,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG15STSA93000004594031","depth":11,"bounds":{"left":0.8828125,"top":0.4848364,"width":0.061668884,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.891","depth":11,"bounds":{"left":0.94830453,"top":0.4848364,"width":0.051695466,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.891","depth":11,"bounds":{"left":1.0,"top":0.4848364,"width":-0.008809805,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.024933511,"top":0.50438946,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.024933511,"top":0.50438946,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"18","depth":11,"bounds":{"left":0.042719416,"top":0.5059856,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit:","depth":11,"bounds":{"left":0.051030584,"top":0.5059856,"width":0.26080453,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"…","depth":11,"bounds":{"left":0.3118351,"top":0.5059856,"width":0.0034906915,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-04 00:00:00","depth":11,"bounds":{"left":0.31831783,"top":0.5059856,"width":0.047706116,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.36884972,"top":0.5059856,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38414228,"top":0.5059856,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ","depth":11,"bounds":{"left":0.42985374,"top":0.5059856,"width":0.11668883,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.09","depth":11,"bounds":{"left":0.5600067,"top":0.5059856,"width":0.009640957,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.57263964,"top":0.5059856,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.60771275,"top":0.5059856,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6218417,"top":0.5059856,"width":0.017785905,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.64261967,"top":0.5059856,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.67852396,"top":0.5059856,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.70977396,"top":0.5059856,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.09","depth":11,"bounds":{"left":0.76545876,"top":0.5059856,"width":0.009807181,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.79488033,"top":0.5059856,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КОМУНАЛНИ УСЛУГИ","depth":11,"bounds":{"left":0.8090093,"top":0.5059856,"width":0.04720745,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG15STSA93000004594031","depth":11,"bounds":{"left":0.8828125,"top":0.5059856,"width":0.061668884,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.906","depth":11,"bounds":{"left":0.94830453,"top":0.5059856,"width":0.051695466,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.906","depth":11,"bounds":{"left":1.0,"top":0.5059856,"width":-0.008809805,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.024933511,"top":0.5255387,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.024933511,"top":0.5255387,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19","depth":11,"bounds":{"left":0.042719416,"top":0.52673584,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 29.54 EUR","depth":11,"bounds":{"left":0.051030584,"top":0.52673584,"width":0.23686835,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-04 00:00:00","depth":11,"bounds":{"left":0.31831783,"top":0.52673584,"width":0.047706116,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.36884972,"top":0.52673584,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38414228,"top":0.52673584,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"С0ФИЙСКА ВОДА ДСК ДИРЕКТ","depth":11,"bounds":{"left":0.42985374,"top":0.52673584,"width":0.068317816,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"29.54","depth":11,"bounds":{"left":0.5571808,"top":0.52673584,"width":0.012466756,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.57263964,"top":0.52673584,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.60771275,"top":0.52673584,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6218417,"top":0.52673584,"width":0.017785905,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.64261967,"top":0.52673584,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.67852396,"top":0.52673584,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.70977396,"top":0.52673584,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"29.54","depth":11,"bounds":{"left":0.7627992,"top":0.52673584,"width":0.012466756,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.79488033,"top":0.52673584,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КОМУНАЛНИ УСЛУГИ","depth":11,"bounds":{"left":0.8090093,"top":0.52673584,"width":0.04720745,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG03STSA93000045940400","depth":11,"bounds":{"left":0.8828125,"top":0.52673584,"width":0.061668884,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.919","depth":11,"bounds":{"left":0.94830453,"top":0.52673584,"width":0.051695466,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.919","depth":11,"bounds":{"left":1.0,"top":0.52673584,"width":-0.008809805,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.024933511,"top":0.5462889,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.024933511,"top":0.5462889,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20","depth":11,"bounds":{"left":0.042719416,"top":0.547486,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА | Debit:","depth":11,"bounds":{"left":0.051030584,"top":0.547486,"width":0.25681517,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"…","depth":11,"bounds":{"left":0.30784574,"top":0.547486,"width":0.003656915,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-04 00:00:00","depth":11,"bounds":{"left":0.31831783,"top":0.547486,"width":0.047706116,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.36884972,"top":0.547486,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38414228,"top":0.547486,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА","depth":11,"bounds":{"left":0.42985374,"top":0.547486,"width":0.112865694,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"14.27","depth":11,"bounds":{"left":0.5571808,"top":0.547486,"width":0.012466756,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.57263964,"top":0.547486,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.60771275,"top":0.547486,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6218417,"top":0.547486,"width":0.017785905,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.64261967,"top":0.547486,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.67852396,"top":0.547486,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.70977396,"top":0.547486,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"14.27","depth":11,"bounds":{"left":0.7627992,"top":0.547486,"width":0.012466756,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.79488033,"top":0.547486,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КОМУНАЛНИ УСЛУГИ","depth":11,"bounds":{"left":0.8090093,"top":0.547486,"width":0.04720745,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG57STSA93000004594051","depth":11,"bounds":{"left":0.8828125,"top":0.547486,"width":0.061668884,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.934","depth":11,"bounds":{"left":0.94830453,"top":0.547486,"width":0.051695466,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.934","depth":11,"bounds":{"left":1.0,"top":0.547486,"width":-0.008809805,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.024933511,"top":0.56703913,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.024933511,"top":0.56703913,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21","depth":11,"bounds":{"left":0.042719416,"top":0.5686353,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 04.05.2026 | Type: ПРЕВОД SEPA | Payee: ЧЦДГ МИЛА | Debit: 460 EUR","depth":11,"bounds":{"left":0.051030584,"top":0.5686353,"width":0.17420213,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-04 00:00:00","depth":11,"bounds":{"left":0.31831783,"top":0.5686353,"width":0.047706116,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.36884972,"top":0.5686353,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38414228,"top":0.5686353,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЧЦДГ МИЛА","depth":11,"bounds":{"left":0.42985374,"top":0.5686353,"width":0.02642952,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"460","depth":11,"bounds":{"left":0.56150264,"top":0.5686353,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.57263964,"top":0.5686353,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.60771275,"top":0.5686353,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6218417,"top":0.5686353,"width":0.017785905,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.64261967,"top":0.5686353,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.67852396,"top":0.5686353,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.70977396,"top":0.5686353,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"460","depth":11,"bounds":{"left":0.767121,"top":0.5686353,"width":0.008144947,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.79488033,"top":0.5686353,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ПРЕВОД SEPA","depth":11,"bounds":{"left":0.8090093,"top":0.5686353,"width":0.030751329,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG43UBBS81551007780277","depth":11,"bounds":{"left":0.8828125,"top":0.5686353,"width":0.06216755,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.945","depth":11,"bounds":{"left":0.94830453,"top":0.5686353,"width":0.051695466,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.945","depth":11,"bounds":{"left":1.0,"top":0.5686353,"width":-0.008809805,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.024933511,"top":0.58818835,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.024933511,"top":0.58818835,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22","depth":11,"bounds":{"left":0.042719416,"top":0.58938545,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 30.04.2026 | Debit: 10.22 EUR","depth":11,"bounds":{"left":0.051030584,"top":0.58938545,"width":0.081615694,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-30 00:00:00","depth":11,"bounds":{"left":0.31831783,"top":0.58938545,"width":0.047706116,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.36884972,"top":0.58938545,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38414228,"top":0.58938545,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.42985374,"top":0.58938545,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.22","depth":11,"bounds":{"left":0.5571808,"top":0.58938545,"width":0.012466756,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.57263964,"top":0.58938545,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.60771275,"top":0.58938545,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6218417,"top":0.58938545,"width":0.017785905,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.64261967,"top":0.58938545,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.67852396,"top":0.58938545,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.70977396,"top":0.58938545,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.22","depth":11,"bounds":{"left":0.7627992,"top":0.58938545,"width":0.012466756,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.79488033,"top":0.58938545,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8090093,"top":0.58938545,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7291133030269999","depth":11,"bounds":{"left":0.8828125,"top":0.58938545,"width":0.043882977,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.955","depth":11,"bounds":{"left":0.94830453,"top":0.58938545,"width":0.051695466,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.955","depth":11,"bounds":{"left":1.0,"top":0.58938545,"width":-0.008809805,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.024933511,"top":0.6089386,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.024933511,"top":0.6089386,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"23","depth":11,"bounds":{"left":0.042719416,"top":0.6105347,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 30.04.2026 | Type: ВХОДЯЩ ПАРИЧЕН ПРЕВОД | Payee: ВЕДА ПЕЙРОЛ ООД | Credit: 4325.26 EUR","depth":11,"bounds":{"left":0.051030584,"top":0.6105347,"width":0.23387633,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-30 00:00:00","depth":11,"bounds":{"left":0.31831783,"top":0.6105347,"width":0.047706116,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.36884972,"top":0.6105347,"width":0.011303191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8235076673930979317
|
7585659470828872979
|
idle
|
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
Select: payments - db - Adminer
Select: payments - db - Adminer
Close tab
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
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
PostgreSQL
PostgreSQL
»
db
db
»
finance_hub
finance_hub
»
public
public
» Select: payments
Select: payments
Select: payments
Select data
Select data
Show structure
Show structure
Alter table
Alter table
New item
New item
Select
Select
Search
Search
Sort
Sort
Limit
50
Text length
100
Action
Select
SELECT
SELECT
*
FROM
"
payments
payments
"
LIMIT
50
(0.001 s)
Edit
Edit
Modify
Modify
id
id
raw_message
raw_message
date
date
type
type
card
card
recipient
recipient
amount
amount
currency
currency
balance
balance
source
source
status
status
notified_at
notified_at
notify_phone
notify_phone
debit_bgn
debit_bgn
credit_bgn
credit_bgn
transaction_type
transaction_type
payer_account
payer_account
created_at
created_at
updated_at
updated_at
edit
edit
1
DSK Bank. Na 08/05/2026 v 10:00 sa iztegleni 200.00 EUR s karta 400915***4447 ot ATM s adres: DSK AT
…
2026-05-08 07:00:00
ATM
400915***4447
DSK ATM, SOFIA, BG
200
EUR
1050
INGEST
UNPROCESSED
NULL
[PHONE]
NULL
NULL
NULL
NULL
2026-05-09 06:44:52.867
2026-05-09 06:44:52.867
edit
edit
2
DSK Bank. Na 08/05/2026 v 19:32 sa plateni 67.81 EUR s karta 400915***4447 na POS s adres: LIDL BALG
…
2026-05-08 16:32:00
POS
400915***4447
LIDL BALGARIYA EOOD, SOFIYA, BGR
67.81
EUR
2011.57
INGEST
UNPROCESSED
NULL
NULL
NULL
NULL
NULL
NULL
2026-05-09 06:59:18.596
2026-05-09 06:59:18.596
edit
edit
9
Date: 08.05.2026 | Debit: 5.02 EUR
2026-05-08 00:00:00
NULL
400915xxxxxx4447
NULL
5.02
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
5.02
NULL
NULL
NULL
2026-05-09 09:29:57.778
2026-05-09 09:29:57.778
edit
edit
10
Date: 08.05.2026 | Debit: 15.46 EUR
2026-05-08 00:00:00
NULL
400915xxxxxx4447
NULL
15.46
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
15.46
NULL
NULL
NULL
2026-05-09 09:29:57.79
2026-05-09 09:29:57.79
edit
edit
11
Date: 08.05.2026 | Debit: 9.04 EUR
2026-05-08 00:00:00
NULL
400915xxxxxx4447
NULL
9.04
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
9.04
NULL
NULL
NULL
2026-05-09 09:29:57.798
2026-05-09 09:29:57.798
edit
edit
12
Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR | Debit:
…
2026-05-08 16:32:00
NULL
400915xxxxxx4447
BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR
67.81
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
67.81
NULL
КАРТОВА ОПЕРАЦИЯ
NULL
2026-05-09 09:29:57.81
2026-05-09 09:29:57.81
edit
edit
13
Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIA CBA EKO MARKET | Debit: 5.51 EUR
2026-05-07 06:02:00
NULL
400915xxxxxx4447
BGR SOFIA CBA EKO MARKET
5.51
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
5.51
NULL
КАРТОВА ОПЕРАЦИЯ
NULL
2026-05-09 09:29:57.827
2026-05-09 09:29:57.827
edit
edit
14
Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: POL BALICE Lagardere Travel R KR3 | Debit: 5.49 E
…
2026-05-06 10:16:00
NULL
400915xxxxxx4447
POL BALICE Lagardere Travel R KR3
5.49
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
5.49
NULL
КАРТОВА ОПЕРАЦИЯ
NULL
2026-05-09 09:29:57.84
2026-05-09 09:29:57.84
edit
edit
15
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ | Debit: 17.93 EUR
2026-05-04 00:00:00
NULL
NULL
КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ
17.93
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
17.93
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.861
2026-05-09 09:29:57.861
edit
edit
16
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 8.44 EUR
2026-05-04 00:00:00
NULL
NULL
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
8.44
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
8.44
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.876
2026-05-09 09:29:57.876
edit
edit
17
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit:
…
2026-05-04 00:00:00
NULL
NULL
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
47.63
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
47.63
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.891
2026-05-09 09:29:57.891
edit
edit
18
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit:
…
2026-05-04 00:00:00
NULL
NULL
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
0.09
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
0.09
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.906
2026-05-09 09:29:57.906
edit
edit
19
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 29.54 EUR
2026-05-04 00:00:00
NULL
NULL
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
29.54
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
29.54
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.919
2026-05-09 09:29:57.919
edit
edit
20
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА | Debit:
…
2026-05-04 00:00:00
NULL
NULL
ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА
14.27
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
14.27
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.934
2026-05-09 09:29:57.934
edit
edit
21
Date: 04.05.2026 | Type: ПРЕВОД SEPA | Payee: ЧЦДГ МИЛА | Debit: 460 EUR
2026-05-04 00:00:00
NULL
NULL
ЧЦДГ МИЛА
460
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
460
NULL
ПРЕВОД SEPA
[IBAN]
2026-05-09 09:29:57.945
2026-05-09 09:29:57.945
edit
edit
22
Date: 30.04.2026 | Debit: 10.22 EUR
2026-04-30 00:00:00
NULL
NULL
NULL
10.22
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
10.22
NULL
NULL
[CREDIT_CARD]
2026-05-09 09:29:57.955
2026-05-09 09:29:57.955
edit
edit
23
Date: 30.04.2026 | Type: ВХОДЯЩ ПАРИЧЕН ПРЕВОД | Payee: ВЕДА ПЕЙРОЛ ООД | Credit: 4325.26 EUR
2026-04-30 00:00:00
NULL...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
12891
|
572
|
0
|
2026-05-09T09:48:25.906820+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778320105906_m2.jpg...
|
Firefox
|
Select: payments - db - Adminer — Personal
|
True
|
http://192.168.0.242:8092/?pgsql=db&username=finan
|
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
Select: payments - db - Adminer
Select: payments - db - Adminer
Close tab
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
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
PostgreSQL
PostgreSQL
»
db
db
»
finance_hub
finance_hub
»
public
public
» Select: payments
Select: payments
Select: payments
Select data
Select data
Show structure
Show structure
Alter table
Alter table
New item
New item
Select
Select
Search
Search
Sort
Sort
Limit
50
Text length
100
Action
Select
SELECT
SELECT
*
FROM
"
payments
payments
"
LIMIT
50
(0.001 s)
Edit
Edit
Modify
Modify
id
id
raw_message
raw_message
date
date
type
type
card
card
recipient
recipient
amount
amount
currency
currency
balance
balance
source
source
status
status
notified_at
notified_at
notify_phone
notify_phone
debit_bgn
debit_bgn
credit_bgn
credit_bgn
transaction_type
transaction_type
payer_account
payer_account
created_at
created_at
updated_at
updated_at
edit
edit
1
DSK Bank. Na 08/05/2026 v 10:00 sa iztegleni 200.00 EUR s karta 400915***4447 ot ATM s adres: DSK AT
…
2026-05-08 07:00:00
ATM
400915***4447
DSK ATM, SOFIA, BG
200
EUR
1050
INGEST
UNPROCESSED
NULL
[PHONE]
NULL
NULL
NULL
NULL
2026-05-09 06:44:52.867
2026-05-09 06:44:52.867
edit
edit
2
DSK Bank. Na 08/05/2026 v 19:32 sa plateni 67.81 EUR s karta 400915***4447 na POS s adres: LIDL BALG
…
2026-05-08 16:32:00
POS
400915***4447
LIDL BALGARIYA EOOD, SOFIYA, BGR
67.81
EUR
2011.57
INGEST
UNPROCESSED
NULL
NULL
NULL
NULL
NULL
NULL
2026-05-09 06:59:18.596
2026-05-09 06:59:18.596
edit
edit
9
Date: 08.05.2026 | Debit: 5.02 EUR
2026-05-08 00:00:00
NULL
400915xxxxxx4447
NULL
5.02
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
5.02
NULL
NULL
NULL
2026-05-09 09:29:57.778
2026-05-09 09:29:57.778
edit
edit
10
Date: 08.05.2026 | Debit: 15.46 EUR
2026-05-08 00:00:00
NULL
400915xxxxxx4447
NULL
15.46
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
15.46
NULL
NULL
NULL
2026-05-09 09:29:57.79
2026-05-09 09:29:57.79
edit
edit
11
Date: 08.05.2026 | Debit: 9.04 EUR
2026-05-08 00:00:00
NULL
400915xxxxxx4447
NULL
9.04
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
9.04
NULL
NULL
NULL
2026-05-09 09:29:57.798
2026-05-09 09:29:57.798
edit
edit
12
Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR | Debit:
…
2026-05-08 16:32:00
NULL
400915xxxxxx4447
BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR
67.81
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
67.81
NULL
КАРТОВА ОПЕРАЦИЯ
NULL
2026-05-09 09:29:57.81
2026-05-09 09:29:57.81
edit
edit
13
Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIA CBA EKO MARKET | Debit: 5.51 EUR
2026-05-07 06:02:00
NULL
400915xxxxxx4447
BGR SOFIA CBA EKO MARKET
5.51
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
5.51
NULL
КАРТОВА ОПЕРАЦИЯ
NULL
2026-05-09 09:29:57.827
2026-05-09 09:29:57.827
edit
edit
14
Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: POL BALICE Lagardere Travel R KR3 | Debit: 5.49 E
…
2026-05-06 10:16:00
NULL
400915xxxxxx4447
POL BALICE Lagardere Travel R KR3
5.49
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
5.49
NULL
КАРТОВА ОПЕРАЦИЯ
NULL
2026-05-09 09:29:57.84
2026-05-09 09:29:57.84
edit
edit
15
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ | Debit: 17.93 EUR
2026-05-04 00:00:00
NULL
NULL
КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ
17.93
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
17.93
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.861
2026-05-09 09:29:57.861
edit
edit
16
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 8.44 EUR
2026-05-04 00:00:00
NULL
NULL
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
8.44
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
8.44
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.876
2026-05-09 09:29:57.876
edit
edit
17
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit:
…
2026-05-04 00:00:00
NULL
NULL
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
47.63
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
47.63
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.891
2026-05-09 09:29:57.891
edit
edit
18
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit:
…
2026-05-04 00:00:00
NULL
NULL
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
0.09
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
0.09
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.906
2026-05-09 09:29:57.906
edit
edit
19
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 29.54 EUR
2026-05-04 00:00:00
NULL
NULL
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
29.54
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
29.54
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.919
2026-05-09 09:29:57.919
edit
edit
20
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА | Debit:
…
2026-05-04 00:00:00
NULL
NULL
ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА
14.27
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
14.27
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.934
2026-05-09 09:29:57.934
edit
edit
21
Date: 04.05.2026 | Type: ПРЕВОД SEPA | Payee: ЧЦДГ МИЛА | Debit: 460 EUR
2026-05-04 00:00:00
NULL
NULL
ЧЦДГ МИЛА
460
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
460
NULL
ПРЕВОД SEPA
[IBAN]
2026-05-09 09:29:57.945
2026-05-09 09:29:57.945
edit
edit
22
Date: 30.04.2026 | Debit: 10.22 EUR
2026-04-30 00:00:00
NULL
NULL
NULL
10.22
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
10.22
NULL
NULL
[CREDIT_CARD]
2026-05-09 09:29:57.955
2026-05-09 09:29:57.955
edit
edit
23
Date: 30.04.2026 | Type: ВХОДЯЩ ПАРИЧЕН ПРЕВОД | Payee: ВЕДА ПЕЙРОЛ ООД | Credit: 4325.26 EUR
2026-04-30 00:00:00
NULL...
|
[{"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":false},{"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":"AXRadioButton","text":"Select: payments - 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":true},{"role":"AXStaticText","text":"Select: payments - db - Adminer","depth":5,"bounds":{"left":0.013297873,"top":0.5865922,"width":0.05651596,"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.5826017,"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":"Електронно банкиране ДСК Директ от Банка ДСК","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":"AXLink","text":"PostgreSQL","depth":8,"bounds":{"left":0.025930852,"top":0.055067837,"width":0.027759308,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"PostgreSQL","depth":9,"bounds":{"left":0.025930852,"top":0.055067837,"width":0.027759308,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"»","depth":8,"bounds":{"left":0.053690158,"top":0.055067837,"width":0.0063164895,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"db","depth":8,"bounds":{"left":0.06000665,"top":0.055067837,"width":0.005984043,"height":0.014365523},"on_screen":true,"help_text":"Alt+Shift+1","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"db","depth":9,"bounds":{"left":0.06000665,"top":0.055067837,"width":0.005984043,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"»","depth":8,"bounds":{"left":0.065990694,"top":0.055067837,"width":0.006482713,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"finance_hub","depth":8,"bounds":{"left":0.07247341,"top":0.055067837,"width":0.029421542,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"finance_hub","depth":9,"bounds":{"left":0.07247341,"top":0.055067837,"width":0.029421542,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"»","depth":8,"bounds":{"left":0.101894945,"top":0.055067837,"width":0.006482713,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"public","depth":8,"bounds":{"left":0.10837766,"top":0.055067837,"width":0.01412899,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"public","depth":9,"bounds":{"left":0.10837766,"top":0.055067837,"width":0.01412899,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"» Select: payments","depth":8,"bounds":{"left":0.12250665,"top":0.055067837,"width":0.048537236,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Select: payments","depth":7,"bounds":{"left":0.021276595,"top":0.0830008,"width":0.9787234,"height":0.04988029},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select: payments","depth":8,"bounds":{"left":0.028424202,"top":0.096568234,"width":0.0631649,"height":0.021548284},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Select data","depth":8,"bounds":{"left":0.027260639,"top":0.14884278,"width":0.029920213,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select data","depth":9,"bounds":{"left":0.027260639,"top":0.14884278,"width":0.029920213,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Show structure","depth":8,"bounds":{"left":0.06549202,"top":0.14884278,"width":0.03656915,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show structure","depth":9,"bounds":{"left":0.06549202,"top":0.14884278,"width":0.03656915,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Alter table","depth":8,"bounds":{"left":0.11037234,"top":0.14884278,"width":0.024933511,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Alter table","depth":9,"bounds":{"left":0.11037234,"top":0.14884278,"width":0.024933511,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New item","depth":8,"bounds":{"left":0.14361702,"top":0.14884278,"width":0.022772606,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New item","depth":9,"bounds":{"left":0.14361702,"top":0.14884278,"width":0.022772606,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Select","depth":10,"bounds":{"left":0.032081116,"top":0.17238627,"width":0.01462766,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select","depth":11,"bounds":{"left":0.032081116,"top":0.17238627,"width":0.01462766,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Search","depth":10,"bounds":{"left":0.060339097,"top":0.17238627,"width":0.01662234,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search","depth":11,"bounds":{"left":0.060339097,"top":0.17238627,"width":0.01662234,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sort","depth":10,"bounds":{"left":0.09075798,"top":0.17238627,"width":0.010139627,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sort","depth":11,"bounds":{"left":0.09075798,"top":0.17238627,"width":0.010139627,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Limit","depth":10,"bounds":{"left":0.114527926,"top":0.17238627,"width":0.011801862,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"50","depth":11,"bounds":{"left":0.115192816,"top":0.19473264,"width":0.005485372,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Text length","depth":10,"bounds":{"left":0.14328457,"top":0.17238627,"width":0.026761968,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"100","depth":11,"bounds":{"left":0.14394946,"top":0.19473264,"width":0.007480053,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Action","depth":10,"bounds":{"left":0.18384309,"top":0.17238627,"width":0.014793883,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Select","depth":10,"bounds":{"left":0.18317819,"top":0.19233839,"width":0.016954787,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"SELECT","depth":9,"bounds":{"left":0.027925532,"top":0.22785315,"width":0.015458777,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SELECT","depth":10,"bounds":{"left":0.027925532,"top":0.22785315,"width":0.015458777,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":9,"bounds":{"left":0.04338431,"top":0.22785315,"width":0.0076462766,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FROM","depth":10,"bounds":{"left":0.051030584,"top":0.22785315,"width":0.010305851,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"","depth":9,"bounds":{"left":0.06399601,"top":0.22785315,"width":0.002493351,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"payments","depth":9,"bounds":{"left":0.06648936,"top":0.22785315,"width":0.020611702,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"payments","depth":10,"bounds":{"left":0.06648936,"top":0.22785315,"width":0.020611702,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"","depth":9,"bounds":{"left":0.087101065,"top":0.22785315,"width":0.0026595744,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"LIMIT","depth":10,"bounds":{"left":0.09225399,"top":0.22785315,"width":0.012965426,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"50","depth":9,"bounds":{"left":0.10771277,"top":0.22785315,"width":0.0051529254,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(0.001 s)","depth":8,"bounds":{"left":0.115192816,"top":0.22905028,"width":0.015791224,"height":0.0103751},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Edit","depth":8,"bounds":{"left":0.13264628,"top":0.22585794,"width":0.009142287,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Edit","depth":9,"bounds":{"left":0.13264628,"top":0.22585794,"width":0.009142287,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Modify","depth":12,"bounds":{"left":0.03723404,"top":0.25339186,"width":0.014295213,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Modify","depth":13,"bounds":{"left":0.03723404,"top":0.25339186,"width":0.014295213,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"id","depth":12,"bounds":{"left":0.05518617,"top":0.254988,"width":0.004488032,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"id","depth":14,"bounds":{"left":0.05518617,"top":0.254988,"width":0.004488032,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"raw_message","depth":12,"bounds":{"left":0.17885639,"top":0.254988,"width":0.03357713,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"raw_message","depth":14,"bounds":{"left":0.17885639,"top":0.254988,"width":0.03357713,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"date","depth":12,"bounds":{"left":0.3492354,"top":0.254988,"width":0.010638298,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"date","depth":14,"bounds":{"left":0.3492354,"top":0.254988,"width":0.010638298,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"type","depth":12,"bounds":{"left":0.3821476,"top":0.254988,"width":0.010638298,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"type","depth":14,"bounds":{"left":0.3821476,"top":0.254988,"width":0.010638298,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"card","depth":12,"bounds":{"left":0.41273272,"top":0.254988,"width":0.010472074,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"card","depth":14,"bounds":{"left":0.41273272,"top":0.254988,"width":0.010472074,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"recipient","depth":12,"bounds":{"left":0.4898604,"top":0.254988,"width":0.02144282,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"recipient","depth":14,"bounds":{"left":0.4898604,"top":0.254988,"width":0.02144282,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"amount","depth":12,"bounds":{"left":0.5628325,"top":0.254988,"width":0.018450798,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"amount","depth":14,"bounds":{"left":0.5628325,"top":0.254988,"width":0.018450798,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"currency","depth":12,"bounds":{"left":0.5859375,"top":0.254988,"width":0.021110373,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"currency","depth":14,"bounds":{"left":0.5859375,"top":0.254988,"width":0.021110373,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"balance","depth":12,"bounds":{"left":0.61170214,"top":0.254988,"width":0.018783245,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"balance","depth":14,"bounds":{"left":0.61170214,"top":0.254988,"width":0.018783245,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"source","depth":12,"bounds":{"left":0.63513964,"top":0.254988,"width":0.016123671,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"source","depth":14,"bounds":{"left":0.63513964,"top":0.254988,"width":0.016123671,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"status","depth":12,"bounds":{"left":0.6640625,"top":0.254988,"width":0.014960106,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"status","depth":14,"bounds":{"left":0.6640625,"top":0.254988,"width":0.014960106,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"notified_at","depth":12,"bounds":{"left":0.6918218,"top":0.254988,"width":0.026595745,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"notified_at","depth":14,"bounds":{"left":0.6918218,"top":0.254988,"width":0.026595745,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"notify_phone","depth":12,"bounds":{"left":0.72423536,"top":0.254988,"width":0.032247342,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"notify_phone","depth":14,"bounds":{"left":0.72423536,"top":0.254988,"width":0.032247342,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"debit_bgn","depth":12,"bounds":{"left":0.76230055,"top":0.254988,"width":0.024601065,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"debit_bgn","depth":14,"bounds":{"left":0.76230055,"top":0.254988,"width":0.024601065,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"credit_bgn","depth":12,"bounds":{"left":0.79138964,"top":0.254988,"width":0.026263298,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"credit_bgn","depth":14,"bounds":{"left":0.79138964,"top":0.254988,"width":0.026263298,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"transaction_type","depth":12,"bounds":{"left":0.83627,"top":0.254988,"width":0.041223403,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"transaction_type","depth":14,"bounds":{"left":0.83627,"top":0.254988,"width":0.041223403,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"payer_account","depth":12,"bounds":{"left":0.90857714,"top":0.254988,"width":0.035904255,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"payer_account","depth":14,"bounds":{"left":0.90857714,"top":0.254988,"width":0.035904255,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"created_at","depth":12,"bounds":{"left":0.97639626,"top":0.254988,"width":0.023603737,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"created_at","depth":14,"bounds":{"left":0.97639626,"top":0.254988,"width":0.023603737,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"updated_at","depth":12,"bounds":{"left":1.0,"top":0.254988,"width":-0.036070466,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"updated_at","depth":14,"bounds":{"left":1.0,"top":0.254988,"width":-0.036070466,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.03723404,"top":0.2745411,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.03723404,"top":0.2745411,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":11,"bounds":{"left":0.057845745,"top":0.27573824,"width":0.0028257978,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DSK Bank. Na 08/05/2026 v 10:00 sa iztegleni 200.00 EUR s karta 400915***4447 ot ATM s adres: DSK AT","depth":11,"bounds":{"left":0.06349734,"top":0.27573824,"width":0.23636968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"…","depth":11,"bounds":{"left":0.29986703,"top":0.27573824,"width":0.0034906915,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-08 07:00:00","depth":11,"bounds":{"left":0.33061835,"top":0.27573824,"width":0.047872342,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ATM","depth":11,"bounds":{"left":0.38131648,"top":0.27573824,"width":0.008976064,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"400915***4447","depth":11,"bounds":{"left":0.39660904,"top":0.27573824,"width":0.035738032,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DSK ATM, SOFIA, BG","depth":11,"bounds":{"left":0.44232047,"top":0.27573824,"width":0.045711435,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":11,"bounds":{"left":0.5739694,"top":0.27573824,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.5851064,"top":0.27573824,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1050","depth":11,"bounds":{"left":0.6203458,"top":0.27573824,"width":0.010970744,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"INGEST","depth":11,"bounds":{"left":0.6343085,"top":0.27573824,"width":0.01662234,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.65508646,"top":0.27573824,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.6909907,"top":0.27573824,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"+359888123456","depth":11,"bounds":{"left":0.72207445,"top":0.27573824,"width":0.036402926,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.7765958,"top":0.27573824,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.80734706,"top":0.27573824,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.82147604,"top":0.27573824,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8952792,"top":0.27573824,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 06:44:52.867","depth":11,"bounds":{"left":0.96077126,"top":0.27573824,"width":0.039228737,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 06:44:52.867","depth":11,"bounds":{"left":1.0,"top":0.27573824,"width":-0.021110415,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.03723404,"top":0.2952913,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.03723404,"top":0.2952913,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2","depth":11,"bounds":{"left":0.057845745,"top":0.29688746,"width":0.0028257978,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DSK Bank. Na 08/05/2026 v 19:32 sa plateni 67.81 EUR s karta 400915***4447 na POS s adres: LIDL BALG","depth":11,"bounds":{"left":0.06349734,"top":0.29688746,"width":0.23803191,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"…","depth":11,"bounds":{"left":0.30152926,"top":0.29688746,"width":0.0034906915,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-08 16:32:00","depth":11,"bounds":{"left":0.33061835,"top":0.29688746,"width":0.047872342,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"POS","depth":11,"bounds":{"left":0.38131648,"top":0.29688746,"width":0.008976064,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"400915***4447","depth":11,"bounds":{"left":0.39660904,"top":0.29688746,"width":0.035738032,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"LIDL BALGARIYA EOOD, SOFIYA, BGR","depth":11,"bounds":{"left":0.44232047,"top":0.29688746,"width":0.08194814,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67.81","depth":11,"bounds":{"left":0.5696476,"top":0.29688746,"width":0.012466756,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.5851064,"top":0.29688746,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2011.57","depth":11,"bounds":{"left":0.61336434,"top":0.29688746,"width":0.017952127,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"INGEST","depth":11,"bounds":{"left":0.6343085,"top":0.29688746,"width":0.01662234,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.65508646,"top":0.29688746,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.6909907,"top":0.29688746,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.72207445,"top":0.29688746,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.7765958,"top":0.29688746,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.80734706,"top":0.29688746,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.82147604,"top":0.29688746,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8952792,"top":0.29688746,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 06:59:18.596","depth":11,"bounds":{"left":0.96077126,"top":0.29688746,"width":0.039228737,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 06:59:18.596","depth":11,"bounds":{"left":1.0,"top":0.29688746,"width":-0.021110415,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.03723404,"top":0.31644055,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.03723404,"top":0.31644055,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9","depth":11,"bounds":{"left":0.057845745,"top":0.31763768,"width":0.0028257978,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 08.05.2026 | Debit: 5.02 EUR","depth":11,"bounds":{"left":0.06349734,"top":0.31763768,"width":0.0787899,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-08 00:00:00","depth":11,"bounds":{"left":0.33061835,"top":0.31763768,"width":0.047872342,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38131648,"top":0.31763768,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"400915xxxxxx4447","depth":11,"bounds":{"left":0.39660904,"top":0.31763768,"width":0.042719416,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.44232047,"top":0.31763768,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.02","depth":11,"bounds":{"left":0.57230717,"top":0.31763768,"width":0.009807181,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.5851064,"top":0.31763768,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.62017953,"top":0.31763768,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6343085,"top":0.31763768,"width":0.01761968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.65508646,"top":0.31763768,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.6909907,"top":0.31763768,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.72207445,"top":0.31763768,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.02","depth":11,"bounds":{"left":0.77792555,"top":0.31763768,"width":0.009807181,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.80734706,"top":0.31763768,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.82147604,"top":0.31763768,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8952792,"top":0.31763768,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.778","depth":11,"bounds":{"left":0.96077126,"top":0.31763768,"width":0.039228737,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.778","depth":11,"bounds":{"left":1.0,"top":0.31763768,"width":-0.021110415,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.03723404,"top":0.33719075,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.03723404,"top":0.33719075,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10","depth":11,"bounds":{"left":0.05518617,"top":0.33838788,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 08.05.2026 | Debit: 15.46 EUR","depth":11,"bounds":{"left":0.06349734,"top":0.33838788,"width":0.081615694,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-08 00:00:00","depth":11,"bounds":{"left":0.33061835,"top":0.33838788,"width":0.047872342,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38131648,"top":0.33838788,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"400915xxxxxx4447","depth":11,"bounds":{"left":0.39660904,"top":0.33838788,"width":0.042719416,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.44232047,"top":0.33838788,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15.46","depth":11,"bounds":{"left":0.5696476,"top":0.33838788,"width":0.012466756,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.5851064,"top":0.33838788,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.62017953,"top":0.33838788,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6343085,"top":0.33838788,"width":0.01761968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.65508646,"top":0.33838788,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.6909907,"top":0.33838788,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.72207445,"top":0.33838788,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15.46","depth":11,"bounds":{"left":0.77509975,"top":0.33838788,"width":0.012632979,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.80734706,"top":0.33838788,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.82147604,"top":0.33838788,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8952792,"top":0.33838788,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.79","depth":11,"bounds":{"left":0.96077126,"top":0.33838788,"width":0.039228737,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.79","depth":11,"bounds":{"left":1.0,"top":0.33838788,"width":-0.021110415,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.03723404,"top":0.35794094,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.03723404,"top":0.35794094,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11","depth":11,"bounds":{"left":0.05518617,"top":0.35953712,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 08.05.2026 | Debit: 9.04 EUR","depth":11,"bounds":{"left":0.06349734,"top":0.35953712,"width":0.0787899,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-08 00:00:00","depth":11,"bounds":{"left":0.33061835,"top":0.35953712,"width":0.047872342,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38131648,"top":0.35953712,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"400915xxxxxx4447","depth":11,"bounds":{"left":0.39660904,"top":0.35953712,"width":0.042719416,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.44232047,"top":0.35953712,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9.04","depth":11,"bounds":{"left":0.57230717,"top":0.35953712,"width":0.009807181,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.5851064,"top":0.35953712,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.62017953,"top":0.35953712,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6343085,"top":0.35953712,"width":0.01761968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.65508646,"top":0.35953712,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.6909907,"top":0.35953712,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.72207445,"top":0.35953712,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9.04","depth":11,"bounds":{"left":0.77792555,"top":0.35953712,"width":0.009807181,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.80734706,"top":0.35953712,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.82147604,"top":0.35953712,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8952792,"top":0.35953712,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.798","depth":11,"bounds":{"left":0.96077126,"top":0.35953712,"width":0.039228737,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.798","depth":11,"bounds":{"left":1.0,"top":0.35953712,"width":-0.021110415,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.03723404,"top":0.3790902,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.03723404,"top":0.3790902,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12","depth":11,"bounds":{"left":0.05518617,"top":0.38028732,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR | Debit:","depth":11,"bounds":{"left":0.06349734,"top":0.38028732,"width":0.24800532,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"…","depth":11,"bounds":{"left":0.31150267,"top":0.38028732,"width":0.0034906915,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-08 16:32:00","depth":11,"bounds":{"left":0.33061835,"top":0.38028732,"width":0.047872342,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38131648,"top":0.38028732,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"400915xxxxxx4447","depth":11,"bounds":{"left":0.39660904,"top":0.38028732,"width":0.042719416,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR","depth":11,"bounds":{"left":0.44232047,"top":0.38028732,"width":0.10305851,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67.81","depth":11,"bounds":{"left":0.5696476,"top":0.38028732,"width":0.012466756,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.5851064,"top":0.38028732,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.62017953,"top":0.38028732,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6343085,"top":0.38028732,"width":0.01761968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.65508646,"top":0.38028732,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.6909907,"top":0.38028732,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.72207445,"top":0.38028732,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67.81","depth":11,"bounds":{"left":0.77509975,"top":0.38028732,"width":0.012632979,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.80734706,"top":0.38028732,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КАРТОВА ОПЕРАЦИЯ","depth":11,"bounds":{"left":0.82147604,"top":0.38028732,"width":0.04637633,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8952792,"top":0.38028732,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.81","depth":11,"bounds":{"left":0.96077126,"top":0.38028732,"width":0.039228737,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.81","depth":11,"bounds":{"left":1.0,"top":0.38028732,"width":-0.021110415,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.03723404,"top":0.39984038,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.03723404,"top":0.39984038,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13","depth":11,"bounds":{"left":0.05518617,"top":0.40143654,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIA CBA EKO MARKET | Debit: 5.51 EUR","depth":11,"bounds":{"left":0.06349734,"top":0.40143654,"width":0.22988696,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-07 06:02:00","depth":11,"bounds":{"left":0.33061835,"top":0.40143654,"width":0.047872342,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38131648,"top":0.40143654,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"400915xxxxxx4447","depth":11,"bounds":{"left":0.39660904,"top":0.40143654,"width":0.042719416,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BGR SOFIA CBA EKO MARKET","depth":11,"bounds":{"left":0.44232047,"top":0.40143654,"width":0.06482713,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.51","depth":11,"bounds":{"left":0.57230717,"top":0.40143654,"width":0.009807181,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.5851064,"top":0.40143654,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.62017953,"top":0.40143654,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6343085,"top":0.40143654,"width":0.01761968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.65508646,"top":0.40143654,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.6909907,"top":0.40143654,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.72207445,"top":0.40143654,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.51","depth":11,"bounds":{"left":0.77792555,"top":0.40143654,"width":0.009807181,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.80734706,"top":0.40143654,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КАРТОВА ОПЕРАЦИЯ","depth":11,"bounds":{"left":0.82147604,"top":0.40143654,"width":0.04637633,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8952792,"top":0.40143654,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.827","depth":11,"bounds":{"left":0.96077126,"top":0.40143654,"width":0.039228737,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.827","depth":11,"bounds":{"left":1.0,"top":0.40143654,"width":-0.021110415,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.03723404,"top":0.42098963,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.03723404,"top":0.42098963,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"14","depth":11,"bounds":{"left":0.05518617,"top":0.42218676,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: POL BALICE Lagardere Travel R KR3 | Debit: 5.49 E","depth":11,"bounds":{"left":0.06349734,"top":0.42218676,"width":0.23686835,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"…","depth":11,"bounds":{"left":0.3003657,"top":0.42218676,"width":0.003656915,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-06 10:16:00","depth":11,"bounds":{"left":0.33061835,"top":0.42218676,"width":0.047872342,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38131648,"top":0.42218676,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"400915xxxxxx4447","depth":11,"bounds":{"left":0.39660904,"top":0.42218676,"width":0.042719416,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"POL BALICE Lagardere Travel R KR3","depth":11,"bounds":{"left":0.44232047,"top":0.42218676,"width":0.078125,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.49","depth":11,"bounds":{"left":0.57230717,"top":0.42218676,"width":0.009807181,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.5851064,"top":0.42218676,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.62017953,"top":0.42218676,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6343085,"top":0.42218676,"width":0.01761968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.65508646,"top":0.42218676,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.6909907,"top":0.42218676,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.72207445,"top":0.42218676,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.49","depth":11,"bounds":{"left":0.77792555,"top":0.42218676,"width":0.009807181,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.80734706,"top":0.42218676,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КАРТОВА ОПЕРАЦИЯ","depth":11,"bounds":{"left":0.82147604,"top":0.42218676,"width":0.04637633,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.8952792,"top":0.42218676,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.84","depth":11,"bounds":{"left":0.96077126,"top":0.42218676,"width":0.039228737,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.84","depth":11,"bounds":{"left":1.0,"top":0.42218676,"width":-0.021110415,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.03723404,"top":0.44173983,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.03723404,"top":0.44173983,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15","depth":11,"bounds":{"left":0.05518617,"top":0.44293696,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ | Debit: 17.93 EUR","depth":11,"bounds":{"left":0.06349734,"top":0.44293696,"width":0.24850398,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-04 00:00:00","depth":11,"bounds":{"left":0.33061835,"top":0.44293696,"width":0.047872342,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38131648,"top":0.44293696,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.39660904,"top":0.44293696,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ","depth":11,"bounds":{"left":0.44232047,"top":0.44293696,"width":0.079953454,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17.93","depth":11,"bounds":{"left":0.5696476,"top":0.44293696,"width":0.012466756,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.5851064,"top":0.44293696,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.62017953,"top":0.44293696,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6343085,"top":0.44293696,"width":0.01761968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.65508646,"top":0.44293696,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.6909907,"top":0.44293696,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.72207445,"top":0.44293696,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17.93","depth":11,"bounds":{"left":0.77509975,"top":0.44293696,"width":0.012632979,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.80734706,"top":0.44293696,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КОМУНАЛНИ УСЛУГИ","depth":11,"bounds":{"left":0.82147604,"top":0.44293696,"width":0.047041222,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG91STSA93000004594021","depth":11,"bounds":{"left":0.8952792,"top":0.44293696,"width":0.061502658,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.861","depth":11,"bounds":{"left":0.96077126,"top":0.44293696,"width":0.039228737,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.861","depth":11,"bounds":{"left":1.0,"top":0.44293696,"width":-0.021110415,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.03723404,"top":0.46249002,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.03723404,"top":0.46249002,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"16","depth":11,"bounds":{"left":0.05518617,"top":0.4640862,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 8.44 EUR","depth":11,"bounds":{"left":0.06349734,"top":0.4640862,"width":0.23404256,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-04 00:00:00","depth":11,"bounds":{"left":0.33061835,"top":0.4640862,"width":0.047872342,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38131648,"top":0.4640862,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.39660904,"top":0.4640862,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"С0ФИЙСКА ВОДА ДСК ДИРЕКТ","depth":11,"bounds":{"left":0.44232047,"top":0.4640862,"width":0.068317816,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8.44","depth":11,"bounds":{"left":0.57230717,"top":0.4640862,"width":0.009807181,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.5851064,"top":0.4640862,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.62017953,"top":0.4640862,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6343085,"top":0.4640862,"width":0.01761968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.65508646,"top":0.4640862,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.6909907,"top":0.4640862,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.72207445,"top":0.4640862,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8.44","depth":11,"bounds":{"left":0.77792555,"top":0.4640862,"width":0.009807181,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.80734706,"top":0.4640862,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КОМУНАЛНИ УСЛУГИ","depth":11,"bounds":{"left":0.82147604,"top":0.4640862,"width":0.047041222,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG03STSA93000045940400","depth":11,"bounds":{"left":0.8952792,"top":0.4640862,"width":0.061502658,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.876","depth":11,"bounds":{"left":0.96077126,"top":0.4640862,"width":0.039228737,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.876","depth":11,"bounds":{"left":1.0,"top":0.4640862,"width":-0.021110415,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.03723404,"top":0.48363927,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.03723404,"top":0.48363927,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17","depth":11,"bounds":{"left":0.05518617,"top":0.4848364,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit:","depth":11,"bounds":{"left":0.06349734,"top":0.4848364,"width":0.26080453,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"…","depth":11,"bounds":{"left":0.32430187,"top":0.4848364,"width":0.0034906915,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-04 00:00:00","depth":11,"bounds":{"left":0.33061835,"top":0.4848364,"width":0.047872342,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38131648,"top":0.4848364,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.39660904,"top":0.4848364,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ","depth":11,"bounds":{"left":0.44232047,"top":0.4848364,"width":0.11668883,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"47.63","depth":11,"bounds":{"left":0.5696476,"top":0.4848364,"width":0.012466756,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.5851064,"top":0.4848364,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.62017953,"top":0.4848364,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6343085,"top":0.4848364,"width":0.01761968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.65508646,"top":0.4848364,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.6909907,"top":0.4848364,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.72207445,"top":0.4848364,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"47.63","depth":11,"bounds":{"left":0.77509975,"top":0.4848364,"width":0.012632979,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.80734706,"top":0.4848364,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КОМУНАЛНИ УСЛУГИ","depth":11,"bounds":{"left":0.82147604,"top":0.4848364,"width":0.047041222,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG15STSA93000004594031","depth":11,"bounds":{"left":0.8952792,"top":0.4848364,"width":0.061502658,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.891","depth":11,"bounds":{"left":0.96077126,"top":0.4848364,"width":0.039228737,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.891","depth":11,"bounds":{"left":1.0,"top":0.4848364,"width":-0.021110415,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.03723404,"top":0.50438946,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.03723404,"top":0.50438946,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"18","depth":11,"bounds":{"left":0.05518617,"top":0.5059856,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit:","depth":11,"bounds":{"left":0.06349734,"top":0.5059856,"width":0.26080453,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"…","depth":11,"bounds":{"left":0.32430187,"top":0.5059856,"width":0.0034906915,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-04 00:00:00","depth":11,"bounds":{"left":0.33061835,"top":0.5059856,"width":0.047872342,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38131648,"top":0.5059856,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.39660904,"top":0.5059856,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ","depth":11,"bounds":{"left":0.44232047,"top":0.5059856,"width":0.11668883,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.09","depth":11,"bounds":{"left":0.57230717,"top":0.5059856,"width":0.009807181,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.5851064,"top":0.5059856,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.62017953,"top":0.5059856,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6343085,"top":0.5059856,"width":0.01761968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.65508646,"top":0.5059856,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.6909907,"top":0.5059856,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.72207445,"top":0.5059856,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.09","depth":11,"bounds":{"left":0.77792555,"top":0.5059856,"width":0.009807181,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.80734706,"top":0.5059856,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КОМУНАЛНИ УСЛУГИ","depth":11,"bounds":{"left":0.82147604,"top":0.5059856,"width":0.047041222,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG15STSA93000004594031","depth":11,"bounds":{"left":0.8952792,"top":0.5059856,"width":0.061502658,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.906","depth":11,"bounds":{"left":0.96077126,"top":0.5059856,"width":0.039228737,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.906","depth":11,"bounds":{"left":1.0,"top":0.5059856,"width":-0.021110415,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.03723404,"top":0.5255387,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.03723404,"top":0.5255387,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19","depth":11,"bounds":{"left":0.05518617,"top":0.52673584,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 29.54 EUR","depth":11,"bounds":{"left":0.06349734,"top":0.52673584,"width":0.23686835,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-04 00:00:00","depth":11,"bounds":{"left":0.33061835,"top":0.52673584,"width":0.047872342,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38131648,"top":0.52673584,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.39660904,"top":0.52673584,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"С0ФИЙСКА ВОДА ДСК ДИРЕКТ","depth":11,"bounds":{"left":0.44232047,"top":0.52673584,"width":0.068317816,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"29.54","depth":11,"bounds":{"left":0.5696476,"top":0.52673584,"width":0.012466756,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.5851064,"top":0.52673584,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.62017953,"top":0.52673584,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6343085,"top":0.52673584,"width":0.01761968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.65508646,"top":0.52673584,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.6909907,"top":0.52673584,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.72207445,"top":0.52673584,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"29.54","depth":11,"bounds":{"left":0.77509975,"top":0.52673584,"width":0.012632979,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.80734706,"top":0.52673584,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КОМУНАЛНИ УСЛУГИ","depth":11,"bounds":{"left":0.82147604,"top":0.52673584,"width":0.047041222,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG03STSA93000045940400","depth":11,"bounds":{"left":0.8952792,"top":0.52673584,"width":0.061502658,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.919","depth":11,"bounds":{"left":0.96077126,"top":0.52673584,"width":0.039228737,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.919","depth":11,"bounds":{"left":1.0,"top":0.52673584,"width":-0.021110415,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.03723404,"top":0.5462889,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.03723404,"top":0.5462889,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20","depth":11,"bounds":{"left":0.05518617,"top":0.547486,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА | Debit:","depth":11,"bounds":{"left":0.06349734,"top":0.547486,"width":0.25681517,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"…","depth":11,"bounds":{"left":0.3203125,"top":0.547486,"width":0.0034906915,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-04 00:00:00","depth":11,"bounds":{"left":0.33061835,"top":0.547486,"width":0.047872342,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38131648,"top":0.547486,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.39660904,"top":0.547486,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА","depth":11,"bounds":{"left":0.44232047,"top":0.547486,"width":0.11269947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"14.27","depth":11,"bounds":{"left":0.5696476,"top":0.547486,"width":0.012466756,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.5851064,"top":0.547486,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.62017953,"top":0.547486,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6343085,"top":0.547486,"width":0.01761968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.65508646,"top":0.547486,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.6909907,"top":0.547486,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.72207445,"top":0.547486,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"14.27","depth":11,"bounds":{"left":0.77509975,"top":0.547486,"width":0.012632979,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.80734706,"top":0.547486,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"КОМУНАЛНИ УСЛУГИ","depth":11,"bounds":{"left":0.82147604,"top":0.547486,"width":0.047041222,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG57STSA93000004594051","depth":11,"bounds":{"left":0.8952792,"top":0.547486,"width":0.061502658,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.934","depth":11,"bounds":{"left":0.96077126,"top":0.547486,"width":0.039228737,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.934","depth":11,"bounds":{"left":1.0,"top":0.547486,"width":-0.021110415,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.03723404,"top":0.56703913,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.03723404,"top":0.56703913,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21","depth":11,"bounds":{"left":0.05518617,"top":0.5686353,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 04.05.2026 | Type: ПРЕВОД SEPA | Payee: ЧЦДГ МИЛА | Debit: 460 EUR","depth":11,"bounds":{"left":0.06349734,"top":0.5686353,"width":0.17420213,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-04 00:00:00","depth":11,"bounds":{"left":0.33061835,"top":0.5686353,"width":0.047872342,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38131648,"top":0.5686353,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.39660904,"top":0.5686353,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ЧЦДГ МИЛА","depth":11,"bounds":{"left":0.44232047,"top":0.5686353,"width":0.02642952,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"460","depth":11,"bounds":{"left":0.5739694,"top":0.5686353,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.5851064,"top":0.5686353,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.62017953,"top":0.5686353,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6343085,"top":0.5686353,"width":0.01761968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.65508646,"top":0.5686353,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.6909907,"top":0.5686353,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.72207445,"top":0.5686353,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"460","depth":11,"bounds":{"left":0.77942157,"top":0.5686353,"width":0.00831117,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.80734706,"top":0.5686353,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ПРЕВОД SEPA","depth":11,"bounds":{"left":0.82147604,"top":0.5686353,"width":0.030751329,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BG43UBBS81551007780277","depth":11,"bounds":{"left":0.8952792,"top":0.5686353,"width":0.06216755,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.945","depth":11,"bounds":{"left":0.96077126,"top":0.5686353,"width":0.039228737,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.945","depth":11,"bounds":{"left":1.0,"top":0.5686353,"width":-0.021110415,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.03723404,"top":0.58818835,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.03723404,"top":0.58818835,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22","depth":11,"bounds":{"left":0.05518617,"top":0.58938545,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 30.04.2026 | Debit: 10.22 EUR","depth":11,"bounds":{"left":0.06349734,"top":0.58938545,"width":0.081615694,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-30 00:00:00","depth":11,"bounds":{"left":0.33061835,"top":0.58938545,"width":0.047872342,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38131648,"top":0.58938545,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.39660904,"top":0.58938545,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.44232047,"top":0.58938545,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.22","depth":11,"bounds":{"left":0.5696476,"top":0.58938545,"width":0.012466756,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":11,"bounds":{"left":0.5851064,"top":0.58938545,"width":0.00880984,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.62017953,"top":0.58938545,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UPLOAD","depth":11,"bounds":{"left":0.6343085,"top":0.58938545,"width":0.01761968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UNPROCESSED","depth":11,"bounds":{"left":0.65508646,"top":0.58938545,"width":0.032912236,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.6909907,"top":0.58938545,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.72207445,"top":0.58938545,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.22","depth":11,"bounds":{"left":0.77509975,"top":0.58938545,"width":0.012632979,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.80734706,"top":0.58938545,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.82147604,"top":0.58938545,"width":0.011136968,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7291133030269999","depth":11,"bounds":{"left":0.8952792,"top":0.58938545,"width":0.043882977,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.955","depth":11,"bounds":{"left":0.96077126,"top":0.58938545,"width":0.039228737,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-05-09 09:29:57.955","depth":11,"bounds":{"left":1.0,"top":0.58938545,"width":-0.021110415,"height":0.0131683955},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"edit","depth":11,"bounds":{"left":0.03723404,"top":0.6089386,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"edit","depth":12,"bounds":{"left":0.03723404,"top":0.6089386,"width":0.008144947,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"23","depth":11,"bounds":{"left":0.05518617,"top":0.6105347,"width":0.005485372,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date: 30.04.2026 | Type: ВХОДЯЩ ПАРИЧЕН ПРЕВОД | Payee: ВЕДА ПЕЙРОЛ ООД | Credit: 4325.26 EUR","depth":11,"bounds":{"left":0.06349734,"top":0.6105347,"width":0.23371011,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-30 00:00:00","depth":11,"bounds":{"left":0.33061835,"top":0.6105347,"width":0.047872342,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NULL","depth":11,"bounds":{"left":0.38131648,"top":0.6105347,"width":0.011136968,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8235076673930979317
|
7585659470828872979
|
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
Select: payments - db - Adminer
Select: payments - db - Adminer
Close tab
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
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
PostgreSQL
PostgreSQL
»
db
db
»
finance_hub
finance_hub
»
public
public
» Select: payments
Select: payments
Select: payments
Select data
Select data
Show structure
Show structure
Alter table
Alter table
New item
New item
Select
Select
Search
Search
Sort
Sort
Limit
50
Text length
100
Action
Select
SELECT
SELECT
*
FROM
"
payments
payments
"
LIMIT
50
(0.001 s)
Edit
Edit
Modify
Modify
id
id
raw_message
raw_message
date
date
type
type
card
card
recipient
recipient
amount
amount
currency
currency
balance
balance
source
source
status
status
notified_at
notified_at
notify_phone
notify_phone
debit_bgn
debit_bgn
credit_bgn
credit_bgn
transaction_type
transaction_type
payer_account
payer_account
created_at
created_at
updated_at
updated_at
edit
edit
1
DSK Bank. Na 08/05/2026 v 10:00 sa iztegleni 200.00 EUR s karta 400915***4447 ot ATM s adres: DSK AT
…
2026-05-08 07:00:00
ATM
400915***4447
DSK ATM, SOFIA, BG
200
EUR
1050
INGEST
UNPROCESSED
NULL
[PHONE]
NULL
NULL
NULL
NULL
2026-05-09 06:44:52.867
2026-05-09 06:44:52.867
edit
edit
2
DSK Bank. Na 08/05/2026 v 19:32 sa plateni 67.81 EUR s karta 400915***4447 na POS s adres: LIDL BALG
…
2026-05-08 16:32:00
POS
400915***4447
LIDL BALGARIYA EOOD, SOFIYA, BGR
67.81
EUR
2011.57
INGEST
UNPROCESSED
NULL
NULL
NULL
NULL
NULL
NULL
2026-05-09 06:59:18.596
2026-05-09 06:59:18.596
edit
edit
9
Date: 08.05.2026 | Debit: 5.02 EUR
2026-05-08 00:00:00
NULL
400915xxxxxx4447
NULL
5.02
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
5.02
NULL
NULL
NULL
2026-05-09 09:29:57.778
2026-05-09 09:29:57.778
edit
edit
10
Date: 08.05.2026 | Debit: 15.46 EUR
2026-05-08 00:00:00
NULL
400915xxxxxx4447
NULL
15.46
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
15.46
NULL
NULL
NULL
2026-05-09 09:29:57.79
2026-05-09 09:29:57.79
edit
edit
11
Date: 08.05.2026 | Debit: 9.04 EUR
2026-05-08 00:00:00
NULL
400915xxxxxx4447
NULL
9.04
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
9.04
NULL
NULL
NULL
2026-05-09 09:29:57.798
2026-05-09 09:29:57.798
edit
edit
12
Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR | Debit:
…
2026-05-08 16:32:00
NULL
400915xxxxxx4447
BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR
67.81
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
67.81
NULL
КАРТОВА ОПЕРАЦИЯ
NULL
2026-05-09 09:29:57.81
2026-05-09 09:29:57.81
edit
edit
13
Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIA CBA EKO MARKET | Debit: 5.51 EUR
2026-05-07 06:02:00
NULL
400915xxxxxx4447
BGR SOFIA CBA EKO MARKET
5.51
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
5.51
NULL
КАРТОВА ОПЕРАЦИЯ
NULL
2026-05-09 09:29:57.827
2026-05-09 09:29:57.827
edit
edit
14
Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: POL BALICE Lagardere Travel R KR3 | Debit: 5.49 E
…
2026-05-06 10:16:00
NULL
400915xxxxxx4447
POL BALICE Lagardere Travel R KR3
5.49
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
5.49
NULL
КАРТОВА ОПЕРАЦИЯ
NULL
2026-05-09 09:29:57.84
2026-05-09 09:29:57.84
edit
edit
15
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ | Debit: 17.93 EUR
2026-05-04 00:00:00
NULL
NULL
КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ
17.93
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
17.93
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.861
2026-05-09 09:29:57.861
edit
edit
16
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 8.44 EUR
2026-05-04 00:00:00
NULL
NULL
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
8.44
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
8.44
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.876
2026-05-09 09:29:57.876
edit
edit
17
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit:
…
2026-05-04 00:00:00
NULL
NULL
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
47.63
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
47.63
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.891
2026-05-09 09:29:57.891
edit
edit
18
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit:
…
2026-05-04 00:00:00
NULL
NULL
ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ
0.09
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
0.09
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.906
2026-05-09 09:29:57.906
edit
edit
19
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 29.54 EUR
2026-05-04 00:00:00
NULL
NULL
С0ФИЙСКА ВОДА ДСК ДИРЕКТ
29.54
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
29.54
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.919
2026-05-09 09:29:57.919
edit
edit
20
Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА | Debit:
…
2026-05-04 00:00:00
NULL
NULL
ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА
14.27
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
14.27
NULL
КОМУНАЛНИ УСЛУГИ
[IBAN]
2026-05-09 09:29:57.934
2026-05-09 09:29:57.934
edit
edit
21
Date: 04.05.2026 | Type: ПРЕВОД SEPA | Payee: ЧЦДГ МИЛА | Debit: 460 EUR
2026-05-04 00:00:00
NULL
NULL
ЧЦДГ МИЛА
460
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
460
NULL
ПРЕВОД SEPA
[IBAN]
2026-05-09 09:29:57.945
2026-05-09 09:29:57.945
edit
edit
22
Date: 30.04.2026 | Debit: 10.22 EUR
2026-04-30 00:00:00
NULL
NULL
NULL
10.22
EUR
NULL
UPLOAD
UNPROCESSED
NULL
NULL
10.22
NULL
NULL
[CREDIT_CARD]
2026-05-09 09:29:57.955
2026-05-09 09:29:57.955
edit
edit
23
Date: 30.04.2026 | Type: ВХОДЯЩ ПАРИЧЕН ПРЕВОД | Payee: ВЕДА ПЕЙРОЛ ООД | Credit: 4325.26 EUR
2026-04-30 00:00:00
NULL...
|
12889
|
NULL
|
NULL
|
NULL
|