|
11627
|
520
|
40
|
2026-05-09T06:42:21.933412+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778308941933_m2.jpg...
|
Code
|
Claude Code — 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
.env
.env.example
.gitignore
docker-compose.yml
payments-logger
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
docker-compose.yml, Editor Group 1
.env, Editor Group 1
version: '3.8'
services:
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: finance
POSTGRES_PASSWORD: [PASSWORD]
POSTGRES_DB: finance_hub
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U finance -d finance_hub"]
interval: 5s
timeout: 5s
retries: 5
backend:
build: ./backend
restart: unless-stopped
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
restart: unless-stopped
ports:
- "${FRONTEND_PORT:-5175}:5173"
depends_on:
- backend
volumes:
pgdata:
version: '3.8'
services:
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: finance
POSTGRES_PASSWORD: [PASSWORD]
POSTGRES_DB: finance_hub
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U finance -d finance_hub"]
interval: 5s
timeout: 5s
retries: 5
backend:
build: ./backend
restart: unless-stopped
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
restart: unless-stopped
ports:
- "${FRONTEND_PORT:-5175}:5173"
depends_on:
- backend
volumes:
pgdata:
Claude Code, Editor Group 2
remote SSH: nas
SSH: nas
No Problems
0
0
No Ports Forwarded
0
Notifications
Sign In
Sign In
Info: Setting up SSH Host nas: Setting up SSH tunnel
Untitled
Session history
New session
Tired of repeating yourself? Tell Claude to remember what you’ve told it using CLAUDE.md.
Prefer the Terminal experience?
Switch back in Settings.
Switch back in Settings.
Close banner
⌘ Esc to focus or unfocus Claude
⌘ Esc to focus or unfocus Claude
Add
Show command menu (/)
docker-compose.yml
docker-compose.yml
Edit automatically
Edit automatically
Local
Local
Web
Web
Untitled now
Untitled
now
Design new payment-logger and dsk-uploader hybrid app 8h
Design new payment-logger and dsk-uploader hybrid app
8h...
|
[{"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":27,"bounds":{"left":0.021276595,"top":0.1819633,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".env","depth":27,"bounds":{"left":0.028590426,"top":0.18355946,"width":0.00831117,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.18435754,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":3,"bounds":{"left":0.029920213,"top":0.18435754,"width":0.006981383,"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.example","depth":27,"bounds":{"left":0.028590426,"top":0.20111732,"width":0.025930852,"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":11,"bounds":{"left":0.029920213,"top":0.2019154,"width":0.024933511,"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":".gitignore","depth":27,"bounds":{"left":0.028590426,"top":0.21867518,"width":0.018949468,"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":9,"bounds":{"left":0.029920213,"top":0.21947326,"width":0.017952127,"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":"docker-compose.yml","depth":27,"bounds":{"left":0.028590426,"top":0.23623304,"width":0.042220745,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.23703113,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":17,"bounds":{"left":0.03125,"top":0.23703113,"width":0.03956117,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.019614361,"top":0.25379092,"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.25379092,"width":0.034574468,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.025930852,"top":0.254589,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":14,"bounds":{"left":0.028590426,"top":0.254589,"width":0.031914894,"height":0.011971269}}],"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":true,"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":"AXStaticText","text":"","depth":29,"bounds":{"left":0.14527926,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextArea","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":28,"bounds":{"left":0.13763298,"top":0.26097366,"width":0.18018617,"height":0.014365523},"on_screen":true,"value":"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:","role_description":"editor","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"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":29,"bounds":{"left":0.13763298,"top":0.26097366,"width":0.18018617,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Claude Code, Editor Group 2","depth":28,"bounds":{"left":0.5578458,"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":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":"AXStaticText","text":"Info: Setting up SSH Host nas: Setting up SSH tunnel","depth":12,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Untitled","depth":19,"bounds":{"left":0.56017286,"top":0.08060654,"width":0.027925532,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Session history","depth":19,"bounds":{"left":0.9780585,"top":0.08060654,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"Session history","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New session","depth":19,"bounds":{"left":0.9886968,"top":0.08060654,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"New session","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Tired of repeating yourself? Tell Claude to remember what you’ve told it using CLAUDE.md.","depth":22,"bounds":{"left":0.73703456,"top":0.5059856,"width":0.084109046,"height":0.046288908},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Prefer the Terminal experience?","depth":22,"bounds":{"left":0.7290558,"top":0.8858739,"width":0.056848403,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.7859042,"top":0.8858739,"width":0.0009973404,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Switch back in Settings.","depth":22,"bounds":{"left":0.7869016,"top":0.8858739,"width":0.043218084,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Switch back in Settings.","depth":23,"bounds":{"left":0.7869016,"top":0.8858739,"width":0.043218084,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Close banner","depth":21,"bounds":{"left":0.82978725,"top":0.88347965,"width":0.0076462766,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"⌘ Esc to focus or unfocus Claude","depth":24,"bounds":{"left":0.6665558,"top":0.9082203,"width":0.22539894,"height":0.0311253},"on_screen":true,"value":"⌘ Esc to focus or unfocus Claude","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"⌘ Esc to focus or unfocus Claude","depth":26,"bounds":{"left":0.6712101,"top":0.91779727,"width":0.06781915,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Add","depth":24,"bounds":{"left":0.6682181,"top":0.94413406,"width":0.008643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show command menu (/)","depth":23,"bounds":{"left":0.6775266,"top":0.94413406,"width":0.008643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"docker-compose.yml","depth":23,"bounds":{"left":0.69049203,"top":0.94413406,"width":0.047872342,"height":0.0207502},"on_screen":true,"help_text":"Showing Claude your current file selection (docker-compose.yml)","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"docker-compose.yml","depth":24,"bounds":{"left":0.69913566,"top":0.9489226,"width":0.03656915,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Edit automatically","depth":24,"bounds":{"left":0.83776593,"top":0.94413406,"width":0.04255319,"height":0.0207502},"on_screen":true,"help_text":"Claude will edit your selected text or the whole file. Click to change, or press Shift+Tab to cycle.","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Edit automatically","depth":25,"bounds":{"left":0.84640956,"top":0.9489226,"width":0.03125,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Local","depth":20,"bounds":{"left":0.85738033,"top":0.11332801,"width":0.0631649,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Local","depth":21,"bounds":{"left":0.88763297,"top":0.118914604,"width":0.009973404,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Web","depth":20,"bounds":{"left":0.9212101,"top":0.11332801,"width":0.0631649,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Web","depth":21,"bounds":{"left":0.9524601,"top":0.118914604,"width":0.00831117,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Untitled now","depth":20,"bounds":{"left":0.85671544,"top":0.16999201,"width":0.12832446,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Untitled","depth":21,"bounds":{"left":0.859375,"top":0.17557861,"width":0.016954787,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"now","depth":21,"bounds":{"left":0.97473407,"top":0.17557861,"width":0.0076462766,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Design new payment-logger and dsk-uploader hybrid app 8h","depth":20,"bounds":{"left":0.85671544,"top":0.19393456,"width":0.12832446,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Design new payment-logger and dsk-uploader hybrid app","depth":21,"bounds":{"left":0.859375,"top":0.19952115,"width":0.10305851,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"8h","depth":21,"bounds":{"left":0.97772604,"top":0.19952115,"width":0.004654255,"height":0.011173184},"on_screen":true,"role_description":"text"}]...
|
-5297263654461112588
|
-4735377878224198777
|
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
.env
.env.example
.gitignore
docker-compose.yml
payments-logger
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
docker-compose.yml, Editor Group 1
.env, Editor Group 1
version: '3.8'
services:
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: finance
POSTGRES_PASSWORD: [PASSWORD]
POSTGRES_DB: finance_hub
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U finance -d finance_hub"]
interval: 5s
timeout: 5s
retries: 5
backend:
build: ./backend
restart: unless-stopped
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
restart: unless-stopped
ports:
- "${FRONTEND_PORT:-5175}:5173"
depends_on:
- backend
volumes:
pgdata:
version: '3.8'
services:
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: finance
POSTGRES_PASSWORD: [PASSWORD]
POSTGRES_DB: finance_hub
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U finance -d finance_hub"]
interval: 5s
timeout: 5s
retries: 5
backend:
build: ./backend
restart: unless-stopped
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
restart: unless-stopped
ports:
- "${FRONTEND_PORT:-5175}:5173"
depends_on:
- backend
volumes:
pgdata:
Claude Code, Editor Group 2
remote SSH: nas
SSH: nas
No Problems
0
0
No Ports Forwarded
0
Notifications
Sign In
Sign In
Info: Setting up SSH Host nas: Setting up SSH tunnel
Untitled
Session history
New session
Tired of repeating yourself? Tell Claude to remember what you’ve told it using CLAUDE.md.
Prefer the Terminal experience?
Switch back in Settings.
Switch back in Settings.
Close banner
⌘ Esc to focus or unfocus Claude
⌘ Esc to focus or unfocus Claude
Add
Show command menu (/)
docker-compose.yml
docker-compose.yml
Edit automatically
Edit automatically
Local
Local
Web
Web
Untitled now
Untitled
now
Design new payment-logger and dsk-uploader hybrid app 8h
Design new payment-logger and dsk-uploader hybrid app
8h...
|
11626
|
NULL
|
NULL
|
NULL
|
|
11892
|
530
|
40
|
2026-05-09T07:12:10.746787+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778310730746_m2.jpg...
|
Code
|
Design new payment-logge… — 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
.env
.env.example
.gitignore
docker-compose.yml
payments-logger
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
docker-compose.yml, Editor Group 1
.env, Editor Group 1
report(1).csv, Editor Group 1
"Дата","Основание","Наредител/Получател","Номер сметка на наредителя / получателя","Вид на трансакцията","Свързваща референция","Валутен курс","Сума във валутата на превода","Дебит EUR","Кредит EUR"
"08.05.2026","400915xxxxxx4447 ПОС 08.05.2026 18:46<br/>Авт. код: 36C1UB","","","","","","","5,02",""
"08.05.2026","400915xxxxxx4447 ПОС 08.05.2026 18:36<br/>Авт. код: 5CK9TB","","","","","","","15,46",""
"08.05.2026","400915xxxxxx4447 ПОС 08.05.2026 18:07<br/>Авт. код: 8FK4TB","","","","","","","9,04",""
"08.05.2026","400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 08.05.2026 19:32<br/>Авт. код: 6NM31C<br/>Номер на у-во: V5411421","BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR","","КАРТОВА ОПЕРАЦИЯ","","","","67,81",""
"08.05.2026","400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 07.05.2026 09:02<br/>Авт. код: 7NE8N7<br/>Номер на у-во: 10101446","BGR SOFIA CBA EKO MARKET","","КАРТОВА ОПЕРАЦИЯ","","","","5,51",""
"08.05.2026","400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 06.05.2026 13:16<br/>Авт. код: 1TV886<br/>Номер на у-во: 06030191","POL BALICE Lagardere Travel R KR3","","КАРТОВА ОПЕРАЦИЯ","","","","5,49",""
"Дата","Основание","Наредител/Получател","Номер сметка на наредителя / получателя","Вид на трансакцията","Свързваща референция","Валутен курс","Сума във валутата на превода","Дебит EUR","Кредит EUR"
"08.05.2026","400915xxxxxx4447 ПОС 08.05.2026 18:46<br/>Авт. код: 36C1UB","","","","","","","5,02",""
"08.05.2026","400915xxxxxx4447 ПОС 08.05.2026 18:36<br/>Авт. код: 5CK9TB","","","","","","","15,46",""
"08.05.2026","400915xxxxxx4447 ПОС 08.05.2026 18:07<br/>Авт. код: 8FK4TB","","","","","","","9,04",""
"08.05.2026","400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 08.05.2026 19:32<br/>Авт. код: 6NM31C<br/>Номер на у-во: V5411421","BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR","","КАРТОВА ОПЕРАЦИЯ","","","","67,81",""
"08.05.2026","400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 07.05.2026 09:02<br/>Авт. код: 7NE8N7<br/>Номер на у-во: 10101446","BGR SOFIA CBA EKO MARKET","","КАРТОВА ОПЕРАЦИЯ","","","","5,51",""
"08.05.2026","400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 06.05.2026 13:16<br/>Авт. код: 1TV886<br/>Номер на у-во: 06030191","POL BALICE Lagardere Travel R KR3","","КАРТОВА ОПЕРАЦИЯ","","","","5,49",""
Design new payment-logge…, Editor Group 2
remote SSH: nas
SSH: nas
No Problems
0
0
No Ports Forwarded
0
Notifications
Sign In
Sign In
Info: Do you want to install the recommended 'Rainbow CSV' extension from mechatroner for report(1).csv?
Design new payment-logger and dsk-uploader hybrid app
Session history
New session
Message actions
payments.js
payments.js
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.
Thinking
Thinking
I'll explore all three reference projects in parallel to understand their structure before planning.
Agent:
Explore payment-logger app structure and functionality
IN
Explore the /volume2/docker/finance/payments-logger directory thoroughly. I need to understand:
1. Tech stack (frontend framework, backend framework, database)
2. What the app does - its core purpose and features
3. Database schema - all tables, relationships
4. API routes - all endpoints, their purpose and request/response shapes
5. How data flows (ingest, storage, retrieval)
6. Any auth/middleware setup
7. Docker/deployment setup
8. Key files and their roles
Report 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.
Agent:
Explore dsk-uploader app structure and functionality
IN
Explore the /volume2/docker/finance/dsk-uploader directory thoroughly. I need to understand:
1. Tech stack (frontend framework, backend framework, database)
2. What the app does - its core purpose and features
3. Database schema - all tables, relationships
4. API routes - all endpoints, their purpose and request/response shapes
5. How file uploads work - what files, what format, how parsed
6. Any auth/middleware setup
7. Docker/deployment setup
8. Key files and their roles
Report 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.
Agent:
Explore auth folder and authentik integration
IN
Explore the /volume2/docker/finance/auth directory thoroughly. I need to understand:
1. What auth system is being used (Authentik)
2. How authentication/authorization is implemented - OAuth2, OIDC, session tokens, JWT?
3. Middleware - how is auth enforced on routes?
4. Any frontend auth flow - login redirect, token handling, protected routes
5. Environment variables related to auth
6. Docker/deployment setup for the auth service itself
7. Any example of how other apps integrate with this auth
Report 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.
Message actions
payments.js
payments.js
continue
Thinking
Thinking
Launching parallel exploration of all three reference projects.
Agent:
Explore payment-logger app structure
IN
Explore the /volume2/docker/finance/payments-logger directory thoroughly. I need to understand:
1. Full directory structure (tree)
2. Tech stack (frontend framework, backend framework, database, etc.)
3. What the app does - its core functionality
4. How data is ingested (look at /ingest route especially)
5. Database schema (what tables/collections exist)
6. API routes and their purposes
7. Frontend pages and components
8. Docker setup
9. Any auth/session handling
Please 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.
Agent:
Explore dsk-uploader app structure
IN
Explore the /volume2/docker/finance/dsk-uploader directory thoroughly. I need to understand:
1. Full directory structure (tree)
2. Tech stack (frontend framework, backend framework, database, etc.)
3. What the app does - its core functionality
4. How file uploads work (what format, what processing happens)
5. Database schema (what tables/collections exist)
6. API routes and their purposes
7. Frontend pages and components
8. Docker setup
9. Any auth/session handling
Please 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.
Agent:
Explore auth project structure
IN
Explore the /volume2/docker/finance/auth directory thoroughly. I need to understand:
1. Full directory structure (tree)
2. What authentication system is used (authentik integration details)
3. How OAuth/OIDC flow works
4. Any middleware or helper functions for protecting routes
5. Session management approach
6. How frontend handles auth state
7. Any example of how other apps integrate with this auth system
8. Docker setup and environment variables
Please read all files carefully - this auth system will be integrated into a new combined app. I need to understand exactly how to use it.
Thinking
Thinking
Now I have a complete picture of all three. Let me design the plan.
Agent:
Design combined app architecture
IN
Design a detailed implementation plan for a new combined web app that merges two existing applications. Here is full context:
---
## App 1: payments-logger (Node.js)
- **Purpose**: Ingest Bulgarian bank SMS → parse → store in PostgreSQL → review/tag/notify in React UI
- **Stack**: Node.js 20 + Express + Prisma 5 + PostgreSQL 16 + React 18 + Vite + Tailwind CSS
- **Auth**: Custom JWT (bcryptjs + jose), tokens in localStorage
- **Ingest**: POST /api/payments/ingest (public) — SMS text OR structured JSON (Apple Wallet)
- **Schema** (PostgreSQL via Prisma):
- `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
- `tags` table: id, name, color — M2M with payments via `_PaymentToTag`
- `users` table: id, username, hashed_password (this will be REMOVED)
- **UI**: Single-page React app — PaymentTable (sortable, filterable, taggable), FilterBar, status actions (send/skip), notification system
- **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
## App 2: dsk-uploader (Python/Flask)
- **Purpose**: Upload DSK bank CSV exports → parse/normalize → upload to Notion database
- **Stack**: Python 3.11 + Flask + Pandas + Custom Notion SDK + Bootstrap 5
- **Auth**: None (open)
- **CSV format** (DSK Bank Bulgarian format, columns):
- `Дата` (date, DD.MM.YYYY)
- `Вид на трансакцията` (transaction type, Bulgarian)
- `Основание` (reason/description — contains card number regex: `^\d{6}x{6}\d{4}$`)
- `Дебит BGN` (debit amount, may be empty)
- `Кредит BGN` (credit amount, may be empty)
- `Наредител/Получател` (orderer/recipient name)
- `Номер сметка на наредителя / получателя` (account number)
- **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
- **Output**: Notion database pages (this will be REPLACED with local PostgreSQL)
## App 3: auth (Authentik)
- **Mode**: Proxy mode via NPM (forward auth)
- **How it works**: NPM intercepts all requests, calls Authentik outpost's auth endpoint. On success, NPM injects headers into proxied request:
- `X-authentik-username`
- `X-authentik-email`
- `X-authentik-groups`
- **No code integration needed** in the app itself — just trust these headers from NPM
- **Logout**: Redirect user to `/outpost.goauthentik.io/sign_out`
---
## What the New Combined App Must Do
1. **Single PostgreSQL database** for all transactions
2. **SMS Ingest** (public endpoint) — same as payments-logger /ingest, source=INGEST
3. **CSV Upload** (authenticated) — parse DSK CSV files, store transactions with source=UPLOAD into the same DB schema
4. **Unified UI** — show all payments in one table regardless of source
5. **Source indicator** in UI — badge showing "INGEST", "UPLOAD", or "BOTH" (if duplicate detection added)
6. **Source filter** in FilterBar — filter by All/Ingest/Upload
7. **Authentik auth** — remove custom JWT entirely; trust X-authentik-* headers from NPM
8. **All existing payments-logger features**: tagging, send notification, skip, status tracking, filters, sorting, pagination
9. **Remove Notion dependency entirely** — all data stays in local PostgreSQL
---
## Technical Constraints
- Keep Node.js backend (not Python) — extend payments-logger's stack
- CSV parsing: use `csv-parse` npm package (handles encoding, streaming)
- File upload: use `multer` npm middleware
- Auth middleware: read X-authentik-username header, 401 if missing (but /api/payments/ingest stays public)
- Add `source` enum field (INGEST/UPLOAD) to payments schema
- Add `currency` field (EUR for SMS ingest, BGN for CSV uploads) — or just store as-is
- Remove `users` table from schema
---
## Please Design
1. Complete folder structure for the new app (suggest name: "finance-hub" or similar — note this is a placeholder, user will confirm)
2. Prisma schema with new fields (`source`, `currency`)
3. All backend API routes
4. CSV parser design in Node.js (port of the Python logic)
5. Authentik auth middleware
6. Frontend component structure (React) — what's reused from payments-logger, what's new
7. Docker Compose setup
8. Environment variables needed
9. Step-by-step implementation order
10. Verification checklist
Be specific about file paths and code structure. This will be used to write actual implementation code.
Thinking
Thinking
Good plan. Let me ask the one thing I need before writing the final plan.
AskUserQuestion
OUT
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.
Thinking
Thinking
Writing the final plan now.
Thinking
Thinking
Write
ets-create-a-new-generic-sun.md
ets-create-a-new-generic-sun.md
326 lines
# finance-hub — Implementation Plan
## Context
Two separate finance apps exist as references and will be retired:
- **payments-logger** (Node.js/React): Ingests Bulgarian bank SMS notifications, stores payments in PostgreSQL, provides a review/tag/notify UI.
- **dsk-uploader** (Python/Flask): Uploads DSK bank CSV exports, parses them, sends to Notion.
The 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).
---
## Tech Stack
| Layer | Choice | Rationale |
|-------|--------|-----------|
| Backend | Node.js 20 + Express + Prisma 5 | Extends payments-logger; no Python needed |
| CSV parsing | `csv-parse` + `iconv-lite` | Handles Bulgarian cp1251 encoding, RFC4180 quoted fields |
| File upload | `multer` (memory storage) | Bank CSVs are small (<500 KB), no disk cleanup needed |
| Database | PostgreSQL 16 | Same as payments-logger |
| Frontend | React 18 + Vite + Tailwind CSS + Lucide React | Same as payments-logger |
| Auth | Authentik proxy via NPM headers | No custom JWT; removes users table entirely |
| Container | Docker Compose | Same pattern as both reference apps |
**Removed vs payments-logger:** `bcryptjs`, `jose`, `users` table, login form, JWT storage.
**Removed vs dsk-uploader:** Python/Flask, Pandas, Notion SDK, all Notion references.
**Added:** `csv-parse`, `iconv-lite`, `multer`, `source` + `currency` fields, `UploadPanel` component.
---
## Folder Structure
```
/volume2/docker/finance/finance-hub/
├── docker-compose.yml
├── .env
├── .env.example
├── .gitignore
├── backend/
│ ├── Dockerfile
│ ├── package.json
│ ├── prisma/
│ │ ├── schema.prisma
│ │ └── migrations/
│ │ ├── migration_lock.toml
│ │ └── 20260508_init/
│ │ └── migration.sql
│ └── src/
│ ├── index.js ← entry point (Authentik middleware wired here)
│ ├── auth.js ← Authentik header middleware (replaces JWT auth)
│ ├── parser.js ← SMS parser (copy verbatim from payments-logger)
│ ├── csvParser.js ← NEW: DSK CSV parser (port of Python dskuploader.py)
│ └── routes/
│ ├── payments.js ← existing routes + source/currency additions
│ └── upload.js ← NEW: POST /api/upload/csv
└── frontend/
├── Dockerfile
├── package.json
├── vite.config.js
├── tailwind.config.js
├── postcss.config.js
├── index.html
└── src/
├── main.jsx ← remove AuthProvider wrapper
├── index.css
├── App.jsx ← remove auth state, add Upload tab toggle
└── components/
├── FilterBar.jsx ← add source filter select
├── PaymentTable.jsx ← add Source badge column + currency display
├── PaymentCard.jsx ← minor source badge addition
├── PaymentList.jsx ← unchanged
└── UploadPanel.jsx ← NEW: drag-and-drop CSV upload UI
```
---
## Database Schema (Prisma)
File: `backend/prisma/schema.prisma`
```prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Payment {
id Int @id @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_empty_lines: true,
trim: true,
relax_column_count: true,
});
parser.on('readable', () => {
let record;
while ((record = parser.read()) !== null) {
try {
const row = processRow(record);
if (row === null) { skipped++; } else { rows.push(row); }
} catch (err) {
errors.push(err.message);
}
}
});
parser.on('error', reject);
parser.on('end', () => resolve({ rows, skipped, errors }));
});
}
module.exports = { parseDskCsv };
Write
index.js
index.js
39 lines
const express = require('express');
const cors = require('cors');
const morgan = require('morgan');
const rateLimit = require('express-rate-limit');
const { authentikMiddleware } = require('./auth');
const paymentsRouter = require('./routes/payments');
const uploadRouter = require('./routes/upload');
const app = express();
const PORT = process.env.PORT || 3001;
app.use(cors());
app.use(express.json({ limit: '16kb' }));
app.use(morgan('combined'));
// Rate-limit the public ingest endpoint before auth middleware
const ingestLimiter = rateLimit({
windowMs...
|
[{"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":27,"bounds":{"left":0.021276595,"top":0.1819633,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".env","depth":27,"bounds":{"left":0.028590426,"top":0.18355946,"width":0.00831117,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.18435754,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":3,"bounds":{"left":0.029920213,"top":0.18435754,"width":0.006981383,"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.example","depth":27,"bounds":{"left":0.028590426,"top":0.20111732,"width":0.025930852,"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":11,"bounds":{"left":0.029920213,"top":0.2019154,"width":0.024933511,"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":".gitignore","depth":27,"bounds":{"left":0.028590426,"top":0.21867518,"width":0.018949468,"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":9,"bounds":{"left":0.029920213,"top":0.21947326,"width":0.017952127,"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":"docker-compose.yml","depth":27,"bounds":{"left":0.028590426,"top":0.23623304,"width":0.042220745,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.23703113,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":17,"bounds":{"left":0.03125,"top":0.23703113,"width":0.03956117,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.019614361,"top":0.25379092,"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.25379092,"width":0.034574468,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.025930852,"top":0.254589,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":14,"bounds":{"left":0.028590426,"top":0.254589,"width":0.031914894,"height":0.011971269}}],"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":true,"is_expanded":false},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.13264628,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.14827128,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.17586437,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextArea","text":"\"Дата\",\"Основание\",\"Наредител/Получател\",\"Номер сметка на наредителя / получателя\",\"Вид на трансакцията\",\"Свързваща референция\",\"Валутен курс\",\"Сума във валутата на превода\",\"Дебит EUR\",\"Кредит EUR\"\n\"08.05.2026\",\"400915xxxxxx4447 ПОС 08.05.2026 18:46<br/>Авт. код: 36C1UB\",\"\",\"\",\"\",\"\",\"\",\"\",\"5,02\",\"\"\n\"08.05.2026\",\"400915xxxxxx4447 ПОС 08.05.2026 18:36<br/>Авт. код: 5CK9TB\",\"\",\"\",\"\",\"\",\"\",\"\",\"15,46\",\"\"\n\"08.05.2026\",\"400915xxxxxx4447 ПОС 08.05.2026 18:07<br/>Авт. код: 8FK4TB\",\"\",\"\",\"\",\"\",\"\",\"\",\"9,04\",\"\"\n\"08.05.2026\",\"400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 08.05.2026 19:32<br/>Авт. код: 6NM31C<br/>Номер на у-во: V5411421\",\"BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR\",\"\",\"КАРТОВА ОПЕРАЦИЯ\",\"\",\"\",\"\",\"67,81\",\"\"\n\"08.05.2026\",\"400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 07.05.2026 09:02<br/>Авт. код: 7NE8N7<br/>Номер на у-во: 10101446\",\"BGR SOFIA CBA EKO MARKET\",\"\",\"КАРТОВА ОПЕРАЦИЯ\",\"\",\"\",\"\",\"5,51\",\"\"\n\"08.05.2026\",\"400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 06.05.2026 13:16<br/>Авт. код: 1TV886<br/>Номер на у-во: 06030191\",\"POL BALICE Lagardere Travel R KR3\",\"\",\"КАРТОВА ОПЕРАЦИЯ\",\"\",\"\",\"\",\"5,49\",\"\"","depth":28,"bounds":{"left":0.13763298,"top":0.0933759,"width":0.42021278,"height":0.014365523},"on_screen":true,"value":"\"Дата\",\"Основание\",\"Наредител/Получател\",\"Номер сметка на наредителя / получателя\",\"Вид на трансакцията\",\"Свързваща референция\",\"Валутен курс\",\"Сума във валутата на превода\",\"Дебит EUR\",\"Кредит EUR\"\n\"08.05.2026\",\"400915xxxxxx4447 ПОС 08.05.2026 18:46<br/>Авт. код: 36C1UB\",\"\",\"\",\"\",\"\",\"\",\"\",\"5,02\",\"\"\n\"08.05.2026\",\"400915xxxxxx4447 ПОС 08.05.2026 18:36<br/>Авт. код: 5CK9TB\",\"\",\"\",\"\",\"\",\"\",\"\",\"15,46\",\"\"\n\"08.05.2026\",\"400915xxxxxx4447 ПОС 08.05.2026 18:07<br/>Авт. код: 8FK4TB\",\"\",\"\",\"\",\"\",\"\",\"\",\"9,04\",\"\"\n\"08.05.2026\",\"400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 08.05.2026 19:32<br/>Авт. код: 6NM31C<br/>Номер на у-во: V5411421\",\"BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR\",\"\",\"КАРТОВА ОПЕРАЦИЯ\",\"\",\"\",\"\",\"67,81\",\"\"\n\"08.05.2026\",\"400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 07.05.2026 09:02<br/>Авт. код: 7NE8N7<br/>Номер на у-во: 10101446\",\"BGR SOFIA CBA EKO MARKET\",\"\",\"КАРТОВА ОПЕРАЦИЯ\",\"\",\"\",\"\",\"5,51\",\"\"\n\"08.05.2026\",\"400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 06.05.2026 13:16<br/>Авт. код: 1TV886<br/>Номер на у-во: 06030191\",\"POL BALICE Lagardere Travel R KR3\",\"\",\"КАРТОВА ОПЕРАЦИЯ\",\"\",\"\",\"\",\"5,49\",\"\"","role_description":"editor","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"\"Дата\",\"Основание\",\"Наредител/Получател\",\"Номер сметка на наредителя / получателя\",\"Вид на трансакцията\",\"Свързваща референция\",\"Валутен курс\",\"Сума във валутата на превода\",\"Дебит EUR\",\"Кредит EUR\"\n\"08.05.2026\",\"400915xxxxxx4447 ПОС 08.05.2026 18:46<br/>Авт. код: 36C1UB\",\"\",\"\",\"\",\"\",\"\",\"\",\"5,02\",\"\"\n\"08.05.2026\",\"400915xxxxxx4447 ПОС 08.05.2026 18:36<br/>Авт. код: 5CK9TB\",\"\",\"\",\"\",\"\",\"\",\"\",\"15,46\",\"\"\n\"08.05.2026\",\"400915xxxxxx4447 ПОС 08.05.2026 18:07<br/>Авт. код: 8FK4TB\",\"\",\"\",\"\",\"\",\"\",\"\",\"9,04\",\"\"\n\"08.05.2026\",\"400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 08.05.2026 19:32<br/>Авт. код: 6NM31C<br/>Номер на у-во: V5411421\",\"BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR\",\"\",\"КАРТОВА ОПЕРАЦИЯ\",\"\",\"\",\"\",\"67,81\",\"\"\n\"08.05.2026\",\"400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 07.05.2026 09:02<br/>Авт. код: 7NE8N7<br/>Номер на у-во: 10101446\",\"BGR SOFIA CBA EKO MARKET\",\"\",\"КАРТОВА ОПЕРАЦИЯ\",\"\",\"\",\"\",\"5,51\",\"\"\n\"08.05.2026\",\"400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 06.05.2026 13:16<br/>Авт. код: 1TV886<br/>Номер на у-во: 06030191\",\"POL BALICE Lagardere Travel R KR3\",\"\",\"КАРТОВА ОПЕРАЦИЯ\",\"\",\"\",\"\",\"5,49\",\"\"","depth":29,"bounds":{"left":0.13763298,"top":0.09497207,"width":0.42021278,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.13763298,"top":0.09497207,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":199,"bounds":{"left":0.13763298,"top":0.09497207,"width":0.47573137,"height":0.025538707}},{"char_start":200,"char_count":109,"bounds":{"left":0.13763298,"top":0.10933759,"width":0.25964096,"height":0.025538707}},{"char_start":309,"char_count":110,"bounds":{"left":0.13763298,"top":0.123703115,"width":0.26196808,"height":0.025538707}},{"char_start":419,"char_count":109,"bounds":{"left":0.13763298,"top":0.13806863,"width":0.25964096,"height":0.025538707}},{"char_start":528,"char_count":211,"bounds":{"left":0.13763298,"top":0.15243416,"width":0.5043218,"height":0.025538707}},{"char_start":739,"char_count":194,"bounds":{"left":0.13763298,"top":0.16679968,"width":0.4637633,"height":0.025538707}},{"char_start":933,"char_count":202,"bounds":{"left":0.13996011,"top":0.1811652,"width":0.48537233,"height":0.011173184}}],"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,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.008643617,"top":0.9856345,"width":0.0013297872,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.009973404,"top":0.9856345,"width":0.01462766,"height":0.011173184}}],"role_description":"text"},{"role":"AXButton","text":"No Problems","depth":16,"bounds":{"left":0.03025266,"top":0.98244214,"width":0.022606382,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.031914894,"top":0.9848364,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":17,"bounds":{"left":0.03723404,"top":0.9856345,"width":0.004986702,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.041888297,"top":0.9848364,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":17,"bounds":{"left":0.04720745,"top":0.9856345,"width":0.0039893617,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"No Ports Forwarded","depth":16,"bounds":{"left":0.054521278,"top":0.98244214,"width":0.012632979,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.05618351,"top":0.9848364,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":17,"bounds":{"left":0.061502658,"top":0.9856345,"width":0.0039893617,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"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,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.97207445,"top":0.9856345,"width":0.0013297872,"height":0.011173184}},{"char_start":1,"char_count":6,"bounds":{"left":0.9734042,"top":0.9856345,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Info: Do you want to install the recommended 'Rainbow CSV' extension from mechatroner for report(1).csv?","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.55984044,"top":0.08060654,"width":0.099734046,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Session history","depth":19,"bounds":{"left":0.9780585,"top":0.08060654,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"Session history","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New session","depth":19,"bounds":{"left":0.9886968,"top":0.08060654,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"New session","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Message actions","depth":24,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"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"},{"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 React components:","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":"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":"11 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"import React from 'react';\nimport ReactDOM from 'react-dom/client';\nimport App from './App';\nimport './index.css';\n\nReactDOM.createRoot(document.getElementById('root')).render(\n <React.StrictMode>\n <App />\n </React.StrictMode>\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":"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":"257 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"import React, { useState, useEffect, useCallback } from 'react';\nimport { LayoutDashboard, Upload, RefreshCw, LogOut } from 'lucide-react';\nimport FilterBar from './components/FilterBar';\nimport PaymentTable from './components/PaymentTable';\nimport UploadPanel from './components/UploadPanel';\n\nconst API_BASE = '/api/payments';\n\nexport default function App() {\n const [activeTab, setActiveTab] = useState('payments');\n const [payments, setPayments] = useState([]);\n const [total, setTotal] = useState(0);\n const [page, setPage] = useState(1);\n const [filters, setFilters] = useState({});\n const [sortBy, setSortBy] = useState('createdAt');\n const [sortDir, setSortDir] = useState('desc');\n const [filterOptions, setFilterOptions] = useState({ types: [], recipients: [], tags: [], sources: [] });\n const [loading, setLoading] = useState(false);\n\n const fetchPayments = useCallback(async () => {\n setLoading(true);\n try {\n const params = new URLSearchParams();\n params.set('page', page);\n params.set('limit', 50);\n params.set('sortBy', sortBy);\n params.set('sortDir', sortDir);\n Object.entries(filters).forEach(([key, val]) => {\n if (val) params.set(key, val);\n });\n const res = await fetch(`${API_BASE}?${params}`);\n const data = await res.json();\n setPayments(data.payments || []);\n setTotal(data.total || 0);\n } catch (err) {\n console.error('Failed to fetch payments:', err);\n } finally {\n setLoading(false);\n }\n }, [page, filters, sortBy, sortDir]);\n\n const fetchFilterOptions = useCallback(async () => {\n try {\n const res = await fetch(`${API_BASE}/meta/filters`);\n const data = await res.json();\n setFilterOptions(data);\n } catch (err) {\n console.error('Failed to fetch filter options:', err);\n }\n }, []);\n\n useEffect(() => {\n fetchPayments();\n }, [fetchPayments]);\n\n useEffect(() => {\n fetchFilterOptions();\n }, [fetchFilterOptions]);\n\n // Refresh payments list after a successful CSV upload\n const handleUploadSuccess = () => {\n fetchPayments();\n fetchFilterOptions();\n setActiveTab('payments');\n };\n\n const handleAction = async (id, action) => {\n try {\n await fetch(`${API_BASE}/${id}/${action}`, { method: 'POST' });\n fetchPayments();\n fetchFilterOptions();\n } catch (err) {\n console.error(`Failed to ${action} payment:`, err);\n }\n };\n\n const handleAddTag = async (id, tagName, tagColor) => {\n try {\n await fetch(`${API_BASE}/${id}/tags`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ name: tagName, color: tagColor }),\n });\n fetchPayments();\n fetchFilterOptions();\n } catch (err) {\n console.error('Failed to add tag:', err);\n }\n };\n\n const handleRemoveTag = async (paymentId, tagId) => {\n try {\n await fetch(`${API_BASE}/${paymentId}/tags/${tagId}`, { method: 'DELETE' });\n fetchPayments();\n } catch (err) {\n console.error('Failed to remove tag:', err);\n }\n };\n\n const handleDelete = async (id) => {\n try {\n await fetch(`${API_BASE}/${id}`, { method: 'DELETE' });\n fetchPayments();\n fetchFilterOptions();\n } catch (err) {\n console.error('Failed to delete payment:', err);\n }\n };\n\n const handleUpdateStatus = async (id, status) => {\n try {\n await fetch(`${API_BASE}/${id}`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ status }),\n });\n fetchPayments();\n } catch (err) {\n console.error('Failed to update status:', err);\n }\n };\n\n const handleFilterChange = (newFilters) => {\n setFilters(newFilters);\n setPage(1);\n };\n\n const handleSort = (field) => {\n if (sortBy === field) {\n setSortDir(d => d === 'asc' ? 'desc' : 'asc');\n } else {\n setSortBy(field);\n setSortDir('desc');\n }\n setPage(1);\n };\n\n const totalPages = Math.ceil(total / 50);\n\n return (\n <div className=\"min-h-screen bg-gray-50\">\n <header className=\"bg-white border-b border-gray-200 shadow-sm\">\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"bg-indigo-600 p-2 rounded-lg\">\n <LayoutDashboard className=\"w-6 h-6 text-white\" />\n </div>\n <div>\n <h1 className=\"text-xl font-bold text-gray-900\">Finance Hub</h1>\n <p className=\"text-sm text-gray-500\">{total} transaction{total !== 1 ? 's' : ''} total</p>\n </div>\n </div>\n\n <div className=\"flex items-center gap-2\">\n {/* Tab switcher */}\n <div className=\"flex items-center rounded-lg border border-gray-200 bg-gray-50 p-1 gap-1\">\n <button\n onClick={() => setActiveTab('payments')}\n className={`flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-md transition-colors ${\n activeTab === 'payments'\n ? 'bg-white text-indigo-700 shadow-sm'\n : 'text-gray-600 hover:text-gray-900'\n }`}\n >\n <LayoutDashboard className=\"w-4 h-4\" />\n Payments\n </button>\n <button\n onClick={() => setActiveTab('upload')}\n className={`flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-md transition-colors ${\n activeTab === 'upload'\n ? 'bg-white text-emerald-700 shadow-sm'\n : 'text-gray-600 hover:text-gray-900'\n }`}\n >\n <Upload className=\"w-4 h-4\" />\n Upload CSV\n </button>\n </div>\n\n {activeTab === 'payments' && (\n <button\n onClick={() => { fetchPayments(); fetchFilterOptions(); }}\n className=\"flex items-center gap-2 px-3 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors\"\n >\n <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />\n Refresh\n </button>\n )}\n\n <button\n onClick={() => { window.location.href = '/outpost.goauthentik.io/sign_out'; }}\n className=\"flex items-center gap-2 px-3 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors\"\n title=\"Sign out\"\n >\n <LogOut className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n </div>\n </header>\n\n <main className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6\">\n {activeTab === 'payments' ? (\n <>\n <FilterBar\n filters={filters}\n filterOptions={filterOptions}\n onFilterChange={handleFilterChange}\n />\n\n <PaymentTable\n payments={payments}\n loading={loading}\n sortBy={sortBy}\n sortDir={sortDir}\n onSort={handleSort}\n onSend={(id) => handleAction(id, 'send')}\n onSkip={(id) => handleAction(id, 'skip')}\n onAddTag={handleAddTag}\n onRemoveTag={handleRemoveTag}\n onDelete={handleDelete}\n onUpdateStatus={handleUpdateStatus}\n existingTags={filterOptions.tags}\n />\n\n {totalPages > 1 && (\n <div className=\"flex items-center justify-center gap-2 mt-6\">\n <button\n onClick={() => setPage(p => Math.max(1, p - 1))}\n disabled={page === 1}\n className=\"px-3 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Previous\n </button>\n <span className=\"text-sm text-gray-600\">\n Page {page} of {totalPages}\n </span>\n <button\n onClick={() => setPage(p => Math.min(totalPages, p + 1))}\n disabled={page === totalPages}\n className=\"px-3 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Next\n </button>\n </div>\n )}\n </>\n ) : (\n <UploadPanel onUploadSuccess={handleUploadSuccess} />\n )}\n </main>\n </div>\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":"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":"167 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"import React, { useState, useEffect } from 'react';\nimport { Search, Filter, X, Calendar, ChevronDown, ChevronUp } from 'lucide-react';\n\nconst STATUS_OPTIONS = [\n { value: '', label: 'All Statuses' },\n { value: 'UNPROCESSED', label: 'Unprocessed' },\n { value: 'SENT', label: 'Sent' },\n { value: 'SKIPPED', label: 'Skipped' },\n];\n\nconst SOURCE_OPTIONS = [\n { value: '', label: 'All Sources' },\n { value: 'INGEST', label: 'SMS Ingest' },\n { value: 'UPLOAD', label: 'CSV Upload' },\n];\n\nexport default function FilterBar({ filters, filterOptions, onFilterChange }) {\n const [search, setSearch] = useState(filters.search || '');\n const [isOpen, setIsOpen] = useState(() => window.innerWidth >= 768);\n\n useEffect(() => {\n const mq = window.matchMedia('(min-width: 768px)');\n const handler = (e) => setIsOpen(e.matches);\n mq.addEventListener('change', handler);\n return () => mq.removeEventListener('change', handler);\n }, []);\n\n const handleSearchSubmit = (e) => {\n e.preventDefault();\n onFilterChange({ ...filters, search: search || undefined });\n };\n\n const handleSelectChange = (key, value) => {\n const newFilters = { ...filters };\n if (value) {\n newFilters[key] = value;\n } else {\n delete newFilters[key];\n }\n onFilterChange(newFilters);\n };\n\n const clearFilters = () => {\n setSearch('');\n onFilterChange({});\n };\n\n const activeFilterCount = Object.keys(filters).length;\n const hasActiveFilters = activeFilterCount > 0;\n\n return (\n <div className=\"bg-white rounded-xl border border-gray-200 shadow-sm p-4 mb-6\">\n <button\n onClick={() => setIsOpen(!isOpen)}\n className=\"w-full flex items-center gap-2\"\n >\n <Filter className=\"w-4 h-4 text-gray-500\" />\n <span className=\"text-sm font-medium text-gray-700\">Filters</span>\n {hasActiveFilters && (\n <span className=\"inline-flex items-center justify-center w-5 h-5 text-xs font-bold text-white bg-indigo-600 rounded-full\">\n {activeFilterCount}\n </span>\n )}\n {hasActiveFilters && (\n <span\n onClick={(e) => { e.stopPropagation(); clearFilters(); }}\n className=\"ml-1 flex items-center gap-1 text-xs text-red-600 hover:text-red-700\"\n >\n <X className=\"w-3 h-3\" />\n Clear\n </span>\n )}\n <span className=\"ml-auto\">\n {isOpen\n ? <ChevronUp className=\"w-4 h-4 text-gray-400\" />\n : <ChevronDown className=\"w-4 h-4 text-gray-400\" />\n }\n </span>\n </button>\n\n {isOpen && (\n <div className=\"space-y-3 mt-3 pt-3 border-t border-gray-100\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-3\">\n <form onSubmit={handleSearchSubmit} className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400\" />\n <input\n type=\"text\"\n placeholder=\"Search...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n onBlur={() => onFilterChange({ ...filters, search: search || undefined })}\n className=\"w-full pl-9 pr-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none\"\n />\n </form>\n\n <select\n value={filters.source || ''}\n onChange={(e) => handleSelectChange('source', e.target.value)}\n className=\"w-full py-2 px-3 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none bg-white\"\n >\n {SOURCE_OPTIONS.map(opt => (\n <option key={opt.value} value={opt.value}>{opt.label}</option>\n ))}\n </select>\n\n <select\n value={filters.status || ''}\n onChange={(e) => handleSelectChange('status', e.target.value)}\n className=\"w-full py-2 px-3 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none bg-white\"\n >\n {STATUS_OPTIONS.map(opt => (\n <option key={opt.value} value={opt.value}>{opt.label}</option>\n ))}\n </select>\n\n <select\n value={filters.type || ''}\n onChange={(e) => handleSelectChange('type', e.target.value)}\n className=\"w-full py-2 px-3 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none bg-white\"\n >\n <option value=\"\">All Types</option>\n {(filterOptions.types || []).map(t => (\n <option key={t} value={t}>{t}</option>\n ))}\n </select>\n\n <select\n value={filters.tag || ''}\n onChange={(e) => handleSelectChange('tag', e.target.value)}\n className=\"w-full py-2 px-3 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none bg-white\"\n >\n <option value=\"\">All Tags</option>\n {(filterOptions.tags || []).map(t => (\n <option key={t.id} value={t.name}>{t.name}</option>\n ))}\n </select>\n </div>\n\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-3\">\n <div className=\"relative\">\n <Calendar className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400\" />\n <input\n type=\"date\"\n placeholder=\"From date\"\n value={filters.dateFrom || ''}\n onChange={(e) => handleSelectChange('dateFrom', e.target.value)}\n className=\"w-full pl-9 pr-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none\"\n />\n </div>\n\n <div className=\"relative\">\n <Calendar className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400\" />\n <input\n type=\"date\"\n placeholder=\"To date\"\n value={filters.dateTo || ''}\n onChange={(e) => handleSelectChange('dateTo', e.target.value)}\n className=\"w-full pl-9 pr-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none\"\n />\n </div>\n </div>\n </div>\n )}\n </div>\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":"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":"AXStaticText","text":"339 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"import React, { useState } from 'react';\nimport {\n ArrowUpDown, ArrowUp, ArrowDown,\n Send, XCircle, CheckCircle, MinusCircle, Clock,\n Inbox, Plus, X, ChevronDown, ChevronUp, Trash2,\n} from 'lucide-react';\n\nconst STATUS_CONFIG = {\n UNPROCESSED: { label: 'Unprocessed', icon: Clock, color: 'bg-amber-100 text-amber-700' },\n SENT: { label: 'Sent', icon: CheckCircle, color: 'bg-green-100 text-green-700' },\n SKIPPED: { label: 'Skipped', icon: MinusCircle, color: 'bg-gray-100 text-gray-500' },\n};\n\nconst TAG_COLORS = [\n '#ef4444', '#f97316', '#eab308', '#22c55e', '#06b6d4',\n '#3b82f6', '#8b5cf6', '#ec4899', '#6b7280',\n];\n\nconst COLUMNS = [\n { key: 'date', label: 'Date & Time', sortable: true },\n { key: 'source', label: 'Source', sortable: true },\n { key: 'type', label: 'Type', sortable: true },\n { key: 'recipient', label: 'Recipient', sortable: true },\n { key: 'amount', label: 'Amount', sortable: true },\n { key: 'balance', label: 'Balance', sortable: true },\n { key: 'status', label: 'Status', sortable: true },\n { key: 'tags', label: 'Tags', sortable: false },\n { key: 'actions', label: 'Actions', sortable: false },\n];\n\nfunction SortIcon({ column, sortBy, sortDir }) {\n if (sortBy !== column) return <ArrowUpDown className=\"w-3 h-3 text-gray-400\" />;\n return sortDir === 'asc'\n ? <ArrowUp className=\"w-3 h-3 text-indigo-600\" />\n : <ArrowDown className=\"w-3 h-3 text-indigo-600\" />;\n}\n\nfunction SourceBadge({ source }) {\n if (source === 'UPLOAD') {\n return (\n <span className=\"px-2 py-0.5 text-xs font-medium rounded bg-emerald-50 text-emerald-700\">\n CSV\n </span>\n );\n }\n return (\n <span className=\"px-2 py-0.5 text-xs font-medium rounded bg-indigo-50 text-indigo-700\">\n SMS\n </span>\n );\n}\n\nfunction TagCell({ payment, onAddTag, onRemoveTag, existingTags }) {\n const [open, setOpen] = useState(false);\n const [newTagName, setNewTagName] = useState('');\n const [newTagColor, setNewTagColor] = useState('#3b82f6');\n\n const paymentTags = payment.tags || [];\n const availableTags = existingTags.filter(t => !paymentTags.some(pt => pt.id === t.id));\n\n const handleAdd = (e) => {\n e.preventDefault();\n if (newTagName.trim()) {\n onAddTag(payment.id, newTagName.trim(), newTagColor);\n setNewTagName('');\n setOpen(false);\n }\n };\n\n return (\n <div className=\"flex flex-wrap items-center gap-1\">\n {paymentTags.map(tag => (\n <span\n key={tag.id}\n className=\"inline-flex items-center gap-0.5 px-1.5 py-0.5 text-xs font-medium rounded-full text-white\"\n style={{ backgroundColor: tag.color }}\n >\n {tag.name}\n <button onClick={() => onRemoveTag(payment.id, tag.id)} className=\"hover:opacity-75\">\n <X className=\"w-2.5 h-2.5\" />\n </button>\n </span>\n ))}\n <div className=\"relative\">\n <button\n onClick={() => setOpen(!open)}\n className=\"inline-flex items-center gap-0.5 px-1.5 py-0.5 text-xs text-gray-500 border border-dashed border-gray-300 rounded-full hover:border-gray-400\"\n >\n <Plus className=\"w-2.5 h-2.5\" />\n </button>\n {open && (\n <div className=\"absolute z-20 top-full left-0 mt-1 bg-white border border-gray-200 rounded-lg shadow-lg p-2 w-56\">\n <form onSubmit={handleAdd} className=\"flex items-center gap-1 mb-2\">\n <input\n type=\"text\"\n value={newTagName}\n onChange={(e) => setNewTagName(e.target.value)}\n placeholder=\"New tag\"\n autoFocus\n className=\"flex-1 px-2 py-1 text-xs border border-gray-300 rounded focus:ring-1 focus:ring-indigo-500 outline-none\"\n />\n <button type=\"submit\" className=\"text-xs text-indigo-600 font-medium hover:text-indigo-700 whitespace-nowrap\">Add</button>\n </form>\n <div className=\"flex gap-1 mb-2\">\n {TAG_COLORS.map(c => (\n <button\n key={c}\n type=\"button\"\n onClick={() => setNewTagColor(c)}\n className={`w-4 h-4 rounded-full border-2 ${newTagColor === c ? 'border-gray-800' : 'border-transparent'}`}\n style={{ backgroundColor: c }}\n />\n ))}\n </div>\n {availableTags.length > 0 && (\n <div className=\"border-t border-gray-100 pt-1 flex flex-wrap gap-1\">\n {availableTags.map(tag => (\n <button\n key={tag.id}\n onClick={() => { onAddTag(payment.id, tag.name, tag.color); setOpen(false); }}\n className=\"px-1.5 py-0.5 text-xs rounded-full border border-gray-200 text-gray-600 hover:bg-gray-100\"\n >\n {tag.name}\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction ExpandedRow({ payment }) {\n return (\n <tr className=\"bg-gray-50\">\n <td colSpan={COLUMNS.length} className=\"px-4 py-3\">\n <div className=\"text-xs text-gray-500 uppercase tracking-wide mb-1\">Original Message / Raw Data</div>\n <p className=\"text-sm text-gray-700 whitespace-pre-wrap break-words\">{payment.rawMessage}</p>\n {payment.debitBgn != null && (\n <p className=\"text-xs text-gray-500 mt-1\">Debit: {payment.debitBgn.toFixed(2)} BGN</p>\n )}\n {payment.creditBgn != null && (\n <p className=\"text-xs text-gray-500 mt-0.5\">Credit: {payment.creditBgn.toFixed(2)} BGN</p>\n )}\n {payment.transactionType && (\n <p className=\"text-xs text-gray-500 mt-0.5\">Transaction type: {payment.transactionType}</p>\n )}\n {payment.payerAccount && (\n <p className=\"text-xs text-gray-500 mt-0.5\">Account: {payment.payerAccount}</p>\n )}\n {payment.notifiedAt && (\n <p className=\"text-xs text-green-600 mt-2\">\n Notified on {new Date(payment.notifiedAt).toLocaleString('en-GB')}\n {payment.notifyPhone && ` to ${payment.notifyPhone}`}\n </p>\n )}\n </td>\n </tr>\n );\n}\n\nfunction StatusCell({ payment, onUpdateStatus }) {\n const [open, setOpen] = useState(false);\n const statusCfg = STATUS_CONFIG[payment.status] || STATUS_CONFIG.UNPROCESSED;\n const StatusIcon = statusCfg.icon;\n\n return (\n <div className=\"relative\">\n <button\n onClick={() => setOpen(!open)}\n className={`inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full cursor-pointer ${statusCfg.color}`}\n >\n <StatusIcon className=\"w-3 h-3\" />\n {statusCfg.label}\n </button>\n {open && (\n <div className=\"absolute z-20 top-full left-0 mt-1 bg-white border border-gray-200 rounded-lg shadow-lg py-1 w-36\">\n {Object.entries(STATUS_CONFIG).map(([key, cfg]) => {\n const Icon = cfg.icon;\n return (\n <button\n key={key}\n onClick={() => { onUpdateStatus(payment.id, key); setOpen(false); }}\n className={`w-full flex items-center gap-2 px-3 py-1.5 text-xs hover:bg-gray-50 ${payment.status === key ? 'font-bold' : ''}`}\n >\n <Icon className=\"w-3 h-3\" />\n {cfg.label}\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n\nexport default function PaymentTable({\n payments, loading, sortBy, sortDir, onSort,\n onSend, onSkip, onAddTag, onRemoveTag, onDelete, onUpdateStatus, existingTags,\n}) {\n const [expandedId, setExpandedId] = useState(null);\n\n if (loading) {\n return (\n <div className=\"flex items-center justify-center py-20\">\n <div className=\"animate-spin rounded-full h-8 w-8 border-b-2 border-indigo-600\"></div>\n </div>\n );\n }\n\n if (!payments || payments.length === 0) {\n return (\n <div className=\"flex flex-col items-center justify-center py-20 text-gray-400\">\n <Inbox className=\"w-12 h-12 mb-3\" />\n <p className=\"text-lg font-medium\">No transactions found</p>\n <p className=\"text-sm\">Try adjusting your filters, ingest a payment SMS, or upload a CSV.</p>\n </div>\n );\n }\n\n const formatDate = (d) => {\n if (!d) return '—';\n return new Date(d).toLocaleDateString('en-GB', {\n day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit',\n });\n };\n\n const formatAmount = (v, currency) =>\n v != null ? `${v.toFixed(2)} ${currency || 'EUR'}` : '—';\n\n return (\n <div className=\"bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"bg-gray-50 border-b border-gray-200\">\n {COLUMNS.map(col => (\n <th\n key={col.key}\n className={`px-4 py-3 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider ${col.sortable ? 'cursor-pointer select-none hover:bg-gray-100' : ''}`}\n onClick={() => col.sortable && onSort(col.key)}\n >\n <span className=\"inline-flex items-center gap-1\">\n {col.label}\n {col.sortable && <SortIcon column={col.key} sortBy={sortBy} sortDir={sortDir} />}\n </span>\n </th>\n ))}\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {payments.map(p => {\n const isExpanded = expandedId === p.id;\n return (\n <React.Fragment key={p.id}>\n <tr className=\"hover:bg-gray-50 transition-colors\">\n <td className=\"px-4 py-3 whitespace-nowrap text-gray-700\">{formatDate(p.date)}</td>\n <td className=\"px-4 py-3 whitespace-nowrap\">\n <SourceBadge source={p.source} />\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap\">\n {p.type ? (\n <span className=\"px-2 py-0.5 text-xs font-medium rounded bg-blue-50 text-blue-700\">{p.type}</span>\n ) : (p.transactionType ? (\n <span className=\"px-2 py-0.5 text-xs font-medium rounded bg-gray-100 text-gray-600 max-w-24 truncate block\" title={p.transactionType}>{p.transactionType}</span>\n ) : '—')}\n </td>\n <td className=\"px-4 py-3 text-gray-700 max-w-xs truncate\" title={p.recipient || ''}>\n <div className=\"flex items-center gap-1\">\n <span className=\"truncate\">{p.recipient || '—'}</span>\n <button\n onClick={() => setExpandedId(isExpanded ? null : p.id)}\n className=\"flex-shrink-0 text-gray-400 hover:text-gray-600\"\n title=\"Show raw data\"\n >\n {isExpanded ? <ChevronUp className=\"w-3.5 h-3.5\" /> : <ChevronDown className=\"w-3.5 h-3.5\" />}\n </button>\n </div>\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap font-medium text-gray-900\">\n {formatAmount(p.amount, p.currency)}\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap text-gray-600\">\n {formatAmount(p.balance, p.currency)}\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap\">\n <StatusCell payment={p} onUpdateStatus={onUpdateStatus} />\n </td>\n <td className=\"px-4 py-3\">\n <TagCell\n payment={p}\n onAddTag={onAddTag}\n onRemoveTag={onRemoveTag}\n existingTags={existingTags}\n />\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap\">\n <div className=\"flex items-center gap-1.5\">\n {p.status === 'UNPROCESSED' && (\n <>\n <button\n onClick={() => onSend(p.id)}\n className=\"inline-flex items-center gap-1 px-2.5 py-1 text-xs font-medium text-white bg-indigo-600 rounded-md hover:bg-indigo-700 transition-colors\"\n >\n <Send className=\"w-3 h-3\" />\n Send\n </button>\n <button\n onClick={() => onSkip(p.id)}\n className=\"inline-flex items-center gap-1 px-2.5 py-1 text-xs font-medium text-gray-600 bg-white border border-gray-300 rounded-md hover:bg-gray-50 transition-colors\"\n >\n <XCircle className=\"w-3 h-3\" />\n Skip\n </button>\n </>\n )}\n <button\n onClick={() => { if (window.confirm('Delete this transaction?')) onDelete(p.id); }}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-xs font-medium text-red-600 bg-white border border-red-200 rounded-md hover:bg-red-50 transition-colors\"\n title=\"Delete transaction\"\n >\n <Trash2 className=\"w-3 h-3\" />\n </button>\n </div>\n </td>\n </tr>\n {isExpanded && <ExpandedRow payment={p} />}\n </React.Fragment>\n );\n })}\n </tbody>\n </table>\n </div>\n </div>\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":"UploadPanel.jsx","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"UploadPanel.jsx","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"192 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"import React, { useState, useRef } from 'react';\nimport { Upload, FileText, CheckCircle, AlertCircle, X, ArrowLeft } from 'lucide-react';\n\nexport default function UploadPanel({ onUploadSuccess }) {\n const [files, setFiles] = useState([]);\n const [loading, setLoading] = useState(false);\n const [result, setResult] = useState(null);\n const [error, setError] = useState(null);\n const [dragging, setDragging] = useState(false);\n const fileInputRef = useRef();\n\n const addFiles = (incoming) => {\n const csvFiles = Array.from(incoming).filter(f =>\n f.name.toLowerCase().endsWith('.csv')\n );\n setFiles(prev => {\n const existingNames = new Set(prev.map(f => f.name));\n return [...prev, ...csvFiles.filter(f => !existingNames.has(f.name))];\n });\n };\n\n const handleDrop = (e) => {\n e.preventDefault();\n setDragging(false);\n addFiles(e.dataTransfer.files);\n };\n\n const handleFileSelect = (e) => {\n addFiles(e.target.files);\n e.target.value = '';\n };\n\n const removeFile = (idx) => setFiles(prev => prev.filter((_, i) => i !== idx));\n\n const handleUpload = async () => {\n if (!files.length) return;\n setLoading(true);\n setError(null);\n setResult(null);\n\n const formData = new FormData();\n files.forEach(f => formData.append('files', f));\n\n try {\n const res = await fetch('/api/upload/csv', { method: 'POST', body: formData });\n const data = await res.json();\n if (!res.ok) throw new Error(data.error || 'Upload failed');\n setResult(data);\n setFiles([]);\n } catch (err) {\n setError(err.message);\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <div className=\"max-w-2xl mx-auto\">\n <div className=\"mb-6\">\n <h2 className=\"text-lg font-semibold text-gray-900\">Upload DSK Bank CSV</h2>\n <p className=\"text-sm text-gray-500 mt-1\">\n Import transactions from DSK Bank CSV exports. Multiple files are merged automatically.\n Internal transfers are skipped. Tags are auto-assigned based on payee and description.\n </p>\n </div>\n\n {/* Drop zone */}\n <div\n onDrop={handleDrop}\n onDragOver={(e) => { e.preventDefault(); setDragging(true); }}\n onDragLeave={() => setDragging(false)}\n onClick={() => fileInputRef.current.click()}\n className={`border-2 border-dashed rounded-xl p-12 text-center cursor-pointer transition-colors ${\n dragging\n ? 'border-emerald-400 bg-emerald-50'\n : 'border-gray-300 hover:border-emerald-400 hover:bg-emerald-50'\n }`}\n >\n <Upload className={`w-10 h-10 mx-auto mb-3 ${dragging ? 'text-emerald-500' : 'text-gray-400'}`} />\n <p className=\"text-sm font-medium text-gray-700\">Drop DSK Bank CSV files here</p>\n <p className=\"text-xs text-gray-500 mt-1\">or click to select files — multiple files supported</p>\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple\n accept=\".csv\"\n className=\"hidden\"\n onChange={handleFileSelect}\n />\n </div>\n\n {/* File list */}\n {files.length > 0 && (\n <div className=\"mt-4 space-y-2\">\n {files.map((f, i) => (\n <div key={i} className=\"flex items-center gap-2 bg-white rounded-lg border border-gray-200 px-3 py-2\">\n <FileText className=\"w-4 h-4 text-gray-400 flex-shrink-0\" />\n <span className=\"text-sm text-gray-700 flex-1 truncate\">{f.name}</span>\n <span className=\"text-xs text-gray-400 flex-shrink-0\">{(f.size / 1024).toFixed(1)} KB</span>\n <button\n onClick={(e) => { e.stopPropagation(); removeFile(i); }}\n className=\"text-gray-400 hover:text-gray-600 flex-shrink-0\"\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n ))}\n\n <button\n onClick={handleUpload}\n disabled={loading}\n className=\"w-full py-2.5 text-sm font-medium text-white bg-emerald-600 rounded-lg hover:bg-emerald-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors mt-2\"\n >\n {loading\n ? 'Importing…'\n : `Import ${files.length} file${files.length !== 1 ? 's' : ''}`\n }\n </button>\n </div>\n )}\n\n {/* Success result */}\n {result && (\n <div className=\"mt-6 bg-green-50 border border-green-200 rounded-xl p-5\">\n <div className=\"flex items-center gap-2 mb-3\">\n <CheckCircle className=\"w-5 h-5 text-green-600 flex-shrink-0\" />\n <span className=\"font-medium text-green-800\">Import complete</span>\n </div>\n <div className=\"grid grid-cols-3 gap-3 text-center mb-3\">\n <div className=\"bg-white rounded-lg border border-green-100 py-2 px-3\">\n <p className=\"text-2xl font-bold text-green-700\">{result.imported}</p>\n <p className=\"text-xs text-gray-500\">Imported</p>\n </div>\n <div className=\"bg-white rounded-lg border border-green-100 py-2 px-3\">\n <p className=\"text-2xl font-bold text-gray-500\">{result.skipped}</p>\n <p className=\"text-xs text-gray-500\">Skipped</p>\n </div>\n <div className=\"bg-white rounded-lg border border-green-100 py-2 px-3\">\n <p className=\"text-2xl font-bold text-amber-600\">{result.errors?.length ?? 0}</p>\n <p className=\"text-xs text-gray-500\">Warnings</p>\n </div>\n </div>\n <p className=\"text-xs text-gray-500 mb-3\">\n Skipped rows are internal bank transfers (ТРАНСФЕР СОБСТВЕНИ СМЕТКИ).\n </p>\n {result.errors?.length > 0 && (\n <details className=\"mb-3\">\n <summary className=\"text-xs text-amber-700 cursor-pointer hover:text-amber-800\">\n Show {result.errors.length} warning{result.errors.length !== 1 ? 's' : ''}\n </summary>\n <ul className=\"mt-2 text-xs text-amber-600 space-y-0.5 max-h-32 overflow-y-auto\">\n {result.errors.map((e, i) => <li key={i} className=\"font-mono\">{e}</li>)}\n </ul>\n </details>\n )}\n <button\n onClick={onUploadSuccess}\n className=\"flex items-center gap-1.5 text-sm font-medium text-green-700 hover:text-green-800\"\n >\n <ArrowLeft className=\"w-4 h-4\" />\n View imported transactions\n </button>\n </div>\n )}\n\n {/* Error */}\n {error && (\n <div className=\"mt-4 bg-red-50 border border-red-200 rounded-xl p-4 flex items-start gap-3\">\n <AlertCircle className=\"w-5 h-5 text-red-500 flex-shrink-0 mt-0.5\" />\n <div>\n <p className=\"text-sm font-medium text-red-800\">Upload failed</p>\n <p className=\"text-sm text-red-700 mt-0.5\">{error}</p>\n </div>\n </div>\n )}\n\n {/* Info box */}\n {!result && !error && (\n <div className=\"mt-6 bg-blue-50 border border-blue-100 rounded-xl p-4\">\n <p className=\"text-xs font-medium text-blue-800 mb-1\">Expected CSV format (DSK Bank export)</p>\n <p className=\"text-xs text-blue-700 font-mono\">\n Дата, Вид на трансакцията, Основание, Дебит BGN, Кредит BGN, Наредител/Получател, Номер сметка...\n </p>\n <p className=\"text-xs text-blue-600 mt-2\">\n Both UTF-8 and Windows-1251 encodings are supported. Tags are auto-applied based on payee and description keywords.\n </p>\n </div>\n )}\n </div>\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":"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":"186 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"import React, { useState } from 'react';\nimport {\n Send, XCircle, CheckCircle, MinusCircle, Clock,\n CreditCard, Tag, Plus, X,\n} from 'lucide-react';\n\nconst STATUS_CONFIG = {\n UNPROCESSED: { label: 'Unprocessed', icon: Clock, color: 'bg-amber-100 text-amber-700 border-amber-200' },\n SENT: { label: 'Sent', icon: CheckCircle, color: 'bg-green-100 text-green-700 border-green-200' },\n SKIPPED: { label: 'Skipped', icon: MinusCircle, color: 'bg-gray-100 text-gray-500 border-gray-200' },\n};\n\nconst TAG_COLORS = [\n '#ef4444', '#f97316', '#eab308', '#22c55e', '#06b6d4',\n '#3b82f6', '#8b5cf6', '#ec4899', '#6b7280',\n];\n\nexport default function PaymentCard({ payment, onSend, onSkip, onAddTag, onRemoveTag, existingTags }) {\n const [showTagInput, setShowTagInput] = useState(false);\n const [newTagName, setNewTagName] = useState('');\n const [newTagColor, setNewTagColor] = useState('#3b82f6');\n\n const statusCfg = STATUS_CONFIG[payment.status] || STATUS_CONFIG.UNPROCESSED;\n const StatusIcon = statusCfg.icon;\n\n const handleAddTag = (e) => {\n e.preventDefault();\n if (newTagName.trim()) {\n onAddTag(payment.id, newTagName.trim(), newTagColor);\n setNewTagName('');\n setShowTagInput(false);\n }\n };\n\n const paymentTags = payment.tags || [];\n const availableTags = existingTags.filter(t => !paymentTags.some(pt => pt.id === t.id));\n\n const formattedDate = payment.date\n ? new Date(payment.date).toLocaleDateString('en-GB', {\n day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit',\n })\n : 'N/A';\n\n const currency = payment.currency || 'EUR';\n\n return (\n <div className=\"bg-white rounded-xl border border-gray-200 shadow-sm hover:shadow-md transition-shadow p-4\">\n <div className=\"flex items-start justify-between gap-3 mb-3\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 mb-1\">\n <span className={`inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full border ${statusCfg.color}`}>\n <StatusIcon className=\"w-3 h-3\" />\n {statusCfg.label}\n </span>\n {payment.source === 'UPLOAD' ? (\n <span className=\"px-2 py-0.5 text-xs font-medium rounded bg-emerald-50 text-emerald-700\">CSV</span>\n ) : (\n <span className=\"px-2 py-0.5 text-xs font-medium rounded bg-indigo-50 text-indigo-700\">SMS</span>\n )}\n </div>\n <p className=\"text-sm text-gray-600 break-words leading-relaxed\">{payment.rawMessage}</p>\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-3 mb-3 text-sm\">\n <div>\n <span className=\"text-xs text-gray-400 uppercase tracking-wide\">Amount</span>\n <p className=\"font-semibold text-gray-900\">\n {payment.amount != null ? `${payment.amount.toFixed(2)} ${currency}` : 'N/A'}\n </p>\n </div>\n <div>\n <span className=\"text-xs text-gray-400 uppercase tracking-wide\">Date</span>\n <p className=\"text-gray-700\">{formattedDate}</p>\n </div>\n <div>\n <span className=\"text-xs text-gray-400 uppercase tracking-wide\">Card</span>\n <p className=\"text-gray-700 flex items-center gap-1\">\n <CreditCard className=\"w-3 h-3 text-gray-400\" />\n {payment.card || 'N/A'}\n </p>\n </div>\n <div>\n <span className=\"text-xs text-gray-400 uppercase tracking-wide\">Balance</span>\n <p className=\"text-gray-700\">\n {payment.balance != null ? `${payment.balance.toFixed(2)} ${currency}` : 'N/A'}\n </p>\n </div>\n </div>\n\n {/* Tags */}\n <div className=\"flex flex-wrap items-center gap-1.5 mb-3\">\n <Tag className=\"w-3 h-3 text-gray-400\" />\n {paymentTags.map(tag => (\n <span\n key={tag.id}\n className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full text-white\"\n style={{ backgroundColor: tag.color }}\n >\n {tag.name}\n <button onClick={() => onRemoveTag(payment.id, tag.id)} className=\"hover:opacity-75\">\n <X className=\"w-3 h-3\" />\n </button>\n </span>\n ))}\n {!showTagInput ? (\n <button\n onClick={() => setShowTagInput(true)}\n className=\"inline-flex items-center gap-0.5 px-2 py-0.5 text-xs text-gray-500 border border-dashed border-gray-300 rounded-full hover:border-gray-400 hover:text-gray-600\"\n >\n <Plus className=\"w-3 h-3\" />\n Tag\n </button>\n ) : (\n <form onSubmit={handleAddTag} className=\"inline-flex items-center gap-1\">\n <input\n type=\"text\"\n value={newTagName}\n onChange={(e) => setNewTagName(e.target.value)}\n placeholder=\"Tag name\"\n autoFocus\n className=\"w-24 px-2 py-0.5 text-xs border border-gray-300 rounded-md focus:ring-1 focus:ring-indigo-500 outline-none\"\n />\n <div className=\"flex gap-0.5\">\n {TAG_COLORS.map(c => (\n <button\n key={c}\n type=\"button\"\n onClick={() => setNewTagColor(c)}\n className={`w-4 h-4 rounded-full border-2 ${newTagColor === c ? 'border-gray-800' : 'border-transparent'}`}\n style={{ backgroundColor: c }}\n />\n ))}\n </div>\n <button type=\"submit\" className=\"text-xs text-indigo-600 font-medium hover:text-indigo-700\">Add</button>\n <button type=\"button\" onClick={() => setShowTagInput(false)} className=\"text-xs text-gray-400 hover:text-gray-600\">\n <X className=\"w-3 h-3\" />\n </button>\n </form>\n )}\n {showTagInput && availableTags.length > 0 && (\n <div className=\"flex flex-wrap gap-1 ml-1\">\n {availableTags.slice(0, 5).map(tag => (\n <button\n key={tag.id}\n onClick={() => { onAddTag(payment.id, tag.name, tag.color); setShowTagInput(false); }}\n className=\"px-2 py-0.5 text-xs rounded-full border border-gray-200 text-gray-600 hover:bg-gray-100\"\n >\n {tag.name}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {payment.status === 'UNPROCESSED' && (\n <div className=\"flex items-center gap-2 pt-3 border-t border-gray-100\">\n <button\n onClick={() => onSend(payment.id)}\n className=\"flex items-center gap-1.5 px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-lg hover:bg-indigo-700 transition-colors\"\n >\n <Send className=\"w-4 h-4\" />\n Send\n </button>\n <button\n onClick={() => onSkip(payment.id)}\n className=\"flex items-center gap-1.5 px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors\"\n >\n <XCircle className=\"w-4 h-4\" />\n Do Not Send\n </button>\n </div>\n )}\n\n {payment.status === 'SENT' && payment.notifiedAt && (\n <div className=\"pt-3 border-t border-gray-100\">\n <p className=\"text-xs text-green-600\">\n Notified on {new Date(payment.notifiedAt).toLocaleString('en-GB')}\n {payment.notifyPhone && ` to ${payment.notifyPhone}`}\n </p>\n </div>\n )}\n </div>\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":"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":"40 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"import React from 'react';\nimport { Inbox } from 'lucide-react';\nimport PaymentCard from './PaymentCard';\n\nexport default function PaymentList({ payments, loading, onSend, onSkip, onAddTag, onRemoveTag, existingTags }) {\n if (loading) {\n return (\n <div className=\"flex items-center justify-center py-20\">\n <div className=\"animate-spin rounded-full h-8 w-8 border-b-2 border-indigo-600\"></div>\n </div>\n );\n }\n\n if (!payments || payments.length === 0) {\n return (\n <div className=\"flex flex-col items-center justify-center py-20 text-gray-400\">\n <Inbox className=\"w-12 h-12 mb-3\" />\n <p className=\"text-lg font-medium\">No transactions found</p>\n <p className=\"text-sm\">Try adjusting your filters, ingest a payment SMS, or upload a CSV.</p>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-4\">\n {payments.map(payment => (\n <PaymentCard\n key={payment.id}\n payment={payment}\n onSend={onSend}\n onSkip={onSkip}\n onAddTag={onAddTag}\n onRemoveTag={onRemoveTag}\n existingTags={existingTags}\n />\n ))}\n </div>\n );\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":"All files are written. Now building:","depth":23,"on_screen":false,"role_description":"text"}]...
|
9123336834367040371
|
6809287908150012859
|
idle
|
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
.env
.env.example
.gitignore
docker-compose.yml
payments-logger
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
docker-compose.yml, Editor Group 1
.env, Editor Group 1
report(1).csv, Editor Group 1
"Дата","Основание","Наредител/Получател","Номер сметка на наредителя / получателя","Вид на трансакцията","Свързваща референция","Валутен курс","Сума във валутата на превода","Дебит EUR","Кредит EUR"
"08.05.2026","400915xxxxxx4447 ПОС 08.05.2026 18:46<br/>Авт. код: 36C1UB","","","","","","","5,02",""
"08.05.2026","400915xxxxxx4447 ПОС 08.05.2026 18:36<br/>Авт. код: 5CK9TB","","","","","","","15,46",""
"08.05.2026","400915xxxxxx4447 ПОС 08.05.2026 18:07<br/>Авт. код: 8FK4TB","","","","","","","9,04",""
"08.05.2026","400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 08.05.2026 19:32<br/>Авт. код: 6NM31C<br/>Номер на у-во: V5411421","BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR","","КАРТОВА ОПЕРАЦИЯ","","","","67,81",""
"08.05.2026","400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 07.05.2026 09:02<br/>Авт. код: 7NE8N7<br/>Номер на у-во: 10101446","BGR SOFIA CBA EKO MARKET","","КАРТОВА ОПЕРАЦИЯ","","","","5,51",""
"08.05.2026","400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 06.05.2026 13:16<br/>Авт. код: 1TV886<br/>Номер на у-во: 06030191","POL BALICE Lagardere Travel R KR3","","КАРТОВА ОПЕРАЦИЯ","","","","5,49",""
"Дата","Основание","Наредител/Получател","Номер сметка на наредителя / получателя","Вид на трансакцията","Свързваща референция","Валутен курс","Сума във валутата на превода","Дебит EUR","Кредит EUR"
"08.05.2026","400915xxxxxx4447 ПОС 08.05.2026 18:46<br/>Авт. код: 36C1UB","","","","","","","5,02",""
"08.05.2026","400915xxxxxx4447 ПОС 08.05.2026 18:36<br/>Авт. код: 5CK9TB","","","","","","","15,46",""
"08.05.2026","400915xxxxxx4447 ПОС 08.05.2026 18:07<br/>Авт. код: 8FK4TB","","","","","","","9,04",""
"08.05.2026","400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 08.05.2026 19:32<br/>Авт. код: 6NM31C<br/>Номер на у-во: V5411421","BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR","","КАРТОВА ОПЕРАЦИЯ","","","","67,81",""
"08.05.2026","400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 07.05.2026 09:02<br/>Авт. код: 7NE8N7<br/>Номер на у-во: 10101446","BGR SOFIA CBA EKO MARKET","","КАРТОВА ОПЕРАЦИЯ","","","","5,51",""
"08.05.2026","400915xxxxxx4447 ПЛАЩАНЕ НА ПОС 06.05.2026 13:16<br/>Авт. код: 1TV886<br/>Номер на у-во: 06030191","POL BALICE Lagardere Travel R KR3","","КАРТОВА ОПЕРАЦИЯ","","","","5,49",""
Design new payment-logge…, Editor Group 2
remote SSH: nas
SSH: nas
No Problems
0
0
No Ports Forwarded
0
Notifications
Sign In
Sign In
Info: Do you want to install the recommended 'Rainbow CSV' extension from mechatroner for report(1).csv?
Design new payment-logger and dsk-uploader hybrid app
Session history
New session
Message actions
payments.js
payments.js
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.
Thinking
Thinking
I'll explore all three reference projects in parallel to understand their structure before planning.
Agent:
Explore payment-logger app structure and functionality
IN
Explore the /volume2/docker/finance/payments-logger directory thoroughly. I need to understand:
1. Tech stack (frontend framework, backend framework, database)
2. What the app does - its core purpose and features
3. Database schema - all tables, relationships
4. API routes - all endpoints, their purpose and request/response shapes
5. How data flows (ingest, storage, retrieval)
6. Any auth/middleware setup
7. Docker/deployment setup
8. Key files and their roles
Report 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.
Agent:
Explore dsk-uploader app structure and functionality
IN
Explore the /volume2/docker/finance/dsk-uploader directory thoroughly. I need to understand:
1. Tech stack (frontend framework, backend framework, database)
2. What the app does - its core purpose and features
3. Database schema - all tables, relationships
4. API routes - all endpoints, their purpose and request/response shapes
5. How file uploads work - what files, what format, how parsed
6. Any auth/middleware setup
7. Docker/deployment setup
8. Key files and their roles
Report 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.
Agent:
Explore auth folder and authentik integration
IN
Explore the /volume2/docker/finance/auth directory thoroughly. I need to understand:
1. What auth system is being used (Authentik)
2. How authentication/authorization is implemented - OAuth2, OIDC, session tokens, JWT?
3. Middleware - how is auth enforced on routes?
4. Any frontend auth flow - login redirect, token handling, protected routes
5. Environment variables related to auth
6. Docker/deployment setup for the auth service itself
7. Any example of how other apps integrate with this auth
Report 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.
Message actions
payments.js
payments.js
continue
Thinking
Thinking
Launching parallel exploration of all three reference projects.
Agent:
Explore payment-logger app structure
IN
Explore the /volume2/docker/finance/payments-logger directory thoroughly. I need to understand:
1. Full directory structure (tree)
2. Tech stack (frontend framework, backend framework, database, etc.)
3. What the app does - its core functionality
4. How data is ingested (look at /ingest route especially)
5. Database schema (what tables/collections exist)
6. API routes and their purposes
7. Frontend pages and components
8. Docker setup
9. Any auth/session handling
Please 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.
Agent:
Explore dsk-uploader app structure
IN
Explore the /volume2/docker/finance/dsk-uploader directory thoroughly. I need to understand:
1. Full directory structure (tree)
2. Tech stack (frontend framework, backend framework, database, etc.)
3. What the app does - its core functionality
4. How file uploads work (what format, what processing happens)
5. Database schema (what tables/collections exist)
6. API routes and their purposes
7. Frontend pages and components
8. Docker setup
9. Any auth/session handling
Please 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.
Agent:
Explore auth project structure
IN
Explore the /volume2/docker/finance/auth directory thoroughly. I need to understand:
1. Full directory structure (tree)
2. What authentication system is used (authentik integration details)
3. How OAuth/OIDC flow works
4. Any middleware or helper functions for protecting routes
5. Session management approach
6. How frontend handles auth state
7. Any example of how other apps integrate with this auth system
8. Docker setup and environment variables
Please read all files carefully - this auth system will be integrated into a new combined app. I need to understand exactly how to use it.
Thinking
Thinking
Now I have a complete picture of all three. Let me design the plan.
Agent:
Design combined app architecture
IN
Design a detailed implementation plan for a new combined web app that merges two existing applications. Here is full context:
---
## App 1: payments-logger (Node.js)
- **Purpose**: Ingest Bulgarian bank SMS → parse → store in PostgreSQL → review/tag/notify in React UI
- **Stack**: Node.js 20 + Express + Prisma 5 + PostgreSQL 16 + React 18 + Vite + Tailwind CSS
- **Auth**: Custom JWT (bcryptjs + jose), tokens in localStorage
- **Ingest**: POST /api/payments/ingest (public) — SMS text OR structured JSON (Apple Wallet)
- **Schema** (PostgreSQL via Prisma):
- `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
- `tags` table: id, name, color — M2M with payments via `_PaymentToTag`
- `users` table: id, username, hashed_password (this will be REMOVED)
- **UI**: Single-page React app — PaymentTable (sortable, filterable, taggable), FilterBar, status actions (send/skip), notification system
- **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
## App 2: dsk-uploader (Python/Flask)
- **Purpose**: Upload DSK bank CSV exports → parse/normalize → upload to Notion database
- **Stack**: Python 3.11 + Flask + Pandas + Custom Notion SDK + Bootstrap 5
- **Auth**: None (open)
- **CSV format** (DSK Bank Bulgarian format, columns):
- `Дата` (date, DD.MM.YYYY)
- `Вид на трансакцията` (transaction type, Bulgarian)
- `Основание` (reason/description — contains card number regex: `^\d{6}x{6}\d{4}$`)
- `Дебит BGN` (debit amount, may be empty)
- `Кредит BGN` (credit amount, may be empty)
- `Наредител/Получател` (orderer/recipient name)
- `Номер сметка на наредителя / получателя` (account number)
- **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
- **Output**: Notion database pages (this will be REPLACED with local PostgreSQL)
## App 3: auth (Authentik)
- **Mode**: Proxy mode via NPM (forward auth)
- **How it works**: NPM intercepts all requests, calls Authentik outpost's auth endpoint. On success, NPM injects headers into proxied request:
- `X-authentik-username`
- `X-authentik-email`
- `X-authentik-groups`
- **No code integration needed** in the app itself — just trust these headers from NPM
- **Logout**: Redirect user to `/outpost.goauthentik.io/sign_out`
---
## What the New Combined App Must Do
1. **Single PostgreSQL database** for all transactions
2. **SMS Ingest** (public endpoint) — same as payments-logger /ingest, source=INGEST
3. **CSV Upload** (authenticated) — parse DSK CSV files, store transactions with source=UPLOAD into the same DB schema
4. **Unified UI** — show all payments in one table regardless of source
5. **Source indicator** in UI — badge showing "INGEST", "UPLOAD", or "BOTH" (if duplicate detection added)
6. **Source filter** in FilterBar — filter by All/Ingest/Upload
7. **Authentik auth** — remove custom JWT entirely; trust X-authentik-* headers from NPM
8. **All existing payments-logger features**: tagging, send notification, skip, status tracking, filters, sorting, pagination
9. **Remove Notion dependency entirely** — all data stays in local PostgreSQL
---
## Technical Constraints
- Keep Node.js backend (not Python) — extend payments-logger's stack
- CSV parsing: use `csv-parse` npm package (handles encoding, streaming)
- File upload: use `multer` npm middleware
- Auth middleware: read X-authentik-username header, 401 if missing (but /api/payments/ingest stays public)
- Add `source` enum field (INGEST/UPLOAD) to payments schema
- Add `currency` field (EUR for SMS ingest, BGN for CSV uploads) — or just store as-is
- Remove `users` table from schema
---
## Please Design
1. Complete folder structure for the new app (suggest name: "finance-hub" or similar — note this is a placeholder, user will confirm)
2. Prisma schema with new fields (`source`, `currency`)
3. All backend API routes
4. CSV parser design in Node.js (port of the Python logic)
5. Authentik auth middleware
6. Frontend component structure (React) — what's reused from payments-logger, what's new
7. Docker Compose setup
8. Environment variables needed
9. Step-by-step implementation order
10. Verification checklist
Be specific about file paths and code structure. This will be used to write actual implementation code.
Thinking
Thinking
Good plan. Let me ask the one thing I need before writing the final plan.
AskUserQuestion
OUT
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.
Thinking
Thinking
Writing the final plan now.
Thinking
Thinking
Write
ets-create-a-new-generic-sun.md
ets-create-a-new-generic-sun.md
326 lines
# finance-hub — Implementation Plan
## Context
Two separate finance apps exist as references and will be retired:
- **payments-logger** (Node.js/React): Ingests Bulgarian bank SMS notifications, stores payments in PostgreSQL, provides a review/tag/notify UI.
- **dsk-uploader** (Python/Flask): Uploads DSK bank CSV exports, parses them, sends to Notion.
The 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).
---
## Tech Stack
| Layer | Choice | Rationale |
|-------|--------|-----------|
| Backend | Node.js 20 + Express + Prisma 5 | Extends payments-logger; no Python needed |
| CSV parsing | `csv-parse` + `iconv-lite` | Handles Bulgarian cp1251 encoding, RFC4180 quoted fields |
| File upload | `multer` (memory storage) | Bank CSVs are small (<500 KB), no disk cleanup needed |
| Database | PostgreSQL 16 | Same as payments-logger |
| Frontend | React 18 + Vite + Tailwind CSS + Lucide React | Same as payments-logger |
| Auth | Authentik proxy via NPM headers | No custom JWT; removes users table entirely |
| Container | Docker Compose | Same pattern as both reference apps |
**Removed vs payments-logger:** `bcryptjs`, `jose`, `users` table, login form, JWT storage.
**Removed vs dsk-uploader:** Python/Flask, Pandas, Notion SDK, all Notion references.
**Added:** `csv-parse`, `iconv-lite`, `multer`, `source` + `currency` fields, `UploadPanel` component.
---
## Folder Structure
```
/volume2/docker/finance/finance-hub/
├── docker-compose.yml
├── .env
├── .env.example
├── .gitignore
├── backend/
│ ├── Dockerfile
│ ├── package.json
│ ├── prisma/
│ │ ├── schema.prisma
│ │ └── migrations/
│ │ ├── migration_lock.toml
│ │ └── 20260508_init/
│ │ └── migration.sql
│ └── src/
│ ├── index.js ← entry point (Authentik middleware wired here)
│ ├── auth.js ← Authentik header middleware (replaces JWT auth)
│ ├── parser.js ← SMS parser (copy verbatim from payments-logger)
│ ├── csvParser.js ← NEW: DSK CSV parser (port of Python dskuploader.py)
│ └── routes/
│ ├── payments.js ← existing routes + source/currency additions
│ └── upload.js ← NEW: POST /api/upload/csv
└── frontend/
├── Dockerfile
├── package.json
├── vite.config.js
├── tailwind.config.js
├── postcss.config.js
├── index.html
└── src/
├── main.jsx ← remove AuthProvider wrapper
├── index.css
├── App.jsx ← remove auth state, add Upload tab toggle
└── components/
├── FilterBar.jsx ← add source filter select
├── PaymentTable.jsx ← add Source badge column + currency display
├── PaymentCard.jsx ← minor source badge addition
├── PaymentList.jsx ← unchanged
└── UploadPanel.jsx ← NEW: drag-and-drop CSV upload UI
```
---
## Database Schema (Prisma)
File: `backend/prisma/schema.prisma`
```prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Payment {
id Int @id @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_empty_lines: true,
trim: true,
relax_column_count: true,
});
parser.on('readable', () => {
let record;
while ((record = parser.read()) !== null) {
try {
const row = processRow(record);
if (row === null) { skipped++; } else { rows.push(row); }
} catch (err) {
errors.push(err.message);
}
}
});
parser.on('error', reject);
parser.on('end', () => resolve({ rows, skipped, errors }));
});
}
module.exports = { parseDskCsv };
Write
index.js
index.js
39 lines
const express = require('express');
const cors = require('cors');
const morgan = require('morgan');
const rateLimit = require('express-rate-limit');
const { authentikMiddleware } = require('./auth');
const paymentsRouter = require('./routes/payments');
const uploadRouter = require('./routes/upload');
const app = express();
const PORT = process.env.PORT || 3001;
app.use(cors());
app.use(express.json({ limit: '16kb' }));
app.use(morgan('combined'));
// Rate-limit the public ingest endpoint before auth middleware
const ingestLimiter = rateLimit({
windowMs...
|
11868
|
NULL
|
NULL
|
NULL
|
|
12351
|
546
|
40
|
2026-05-09T08:47:31.583463+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778316451583_m2.jpg...
|
Firefox
|
Vesselin Petrunov - Software Еngineering Manager r Vesselin Petrunov - Software Еngineering Manager reacted to this post: Забелязвам една плашеща… - kovaliklukas@gmail.com - Gmail — Personal...
|
True
|
mail.google.com/mail/u/0/#inbox/FMfcgzQgLjSzsqsNmB mail.google.com/mail/u/0/#inbox/FMfcgzQgLjSzsqsNmBGZqjCXhLXFpnNq...
|
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
Vesselin Petrunov - Software Еngineering Manager reacted to this post: Забелязвам една плашеща… - [EMAIL] - Gmail
Vesselin Petrunov - Software Еngineering Manager reacted to this post: Забелязвам една плашеща… - [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 21 unread
Inbox
21
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 8784 unread has menu
Updates
8,784
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
22
of
21,245
Newer
Older
Input tools on/off (Ctrl-Shift-K)
Select input tool
Print all
In new window
Vesselin Petrunov - Software Еngineering Manager reacted to this post: Забелязвам една плашеща…
Vesselin Petrunov - Software Еngineering Manager reacted to this post: Забелязвам една плашеща…
Important according to Google magic
Search for all messages with label Inbox
Remove label Inbox from this conversation
LinkedIn Verified sender [EMAIL] Unsubscribe
LinkedIn Verified sender [EMAIL]
LinkedIn
Verified sender
[EMAIL]
Unsubscribe
Unsubscribe
Wed 6 May, 19:47 (3 days ago)
Wed 6 May, 19:47 (3 days ago)
Not starred
You can't react to a group with an emoji
Reply
More message options
to
me
Show details
Забелязвам една плашеща…
͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏
LinkedIn
Messaging icon
Mynetwork icon
Notifications icon
Vesselin Petrunov Vesselin Petrunov liked this Shule Y. Shule Y. Founder & Strategic Architect @ Tech Bridge |… Follow Забелязвам една плашеща тенденция, че всеки втори е експерт по ИИ… Едно е да използваш ИИ като потребител в… see more LIKE PRAISE INTEREST 61 ·57 Comments Read more
Vesselin Petrunov
Vesselin Petrunov
liked this
Shule Y. Shule Y. Founder & Strategic Architect @ Tech Bridge |…
Follow
Забелязвам една плашеща тенденция, че всеки втори е експерт по ИИ… Едно е да използваш ИИ като потребител в…
see more
see more
61
·
57 Comments
Read more
Nikolay Yankov Nikolay Yankov liked this Mollie Luckhurst Mollie Luckhurst Strategic Operator | Scaling SaaS Businesses | CS… Follow I don’t think I’ve bought my own laptop in about 20 years. It’s always been work-issued or the occasional… see more LIKE PRAISE EMPATHY 69 ·13 Comments Read more Read more
Nikolay Yankov
Nikolay Yankov
liked this
Mollie Luckhurst Mollie Luckhurst Strategic Operator | Scaling SaaS Businesses | CS…
Follow
I don’t think I’ve bought my own laptop in about 20 years. It’s always been work-issued or the occasional…
see more
see more
69
·
13 Comments
Read more
Read more
Tsvetomir Banovski Tsvetomir Banovski celebrated this Alexander Semov / Александър Семов Alexander Semov / Александър Семов 1ˢᵗ on LinkedIn Bulgaria for Workplace Well-Being &… Follow Много често чувах от хората, че няма да успее, защото няма пари... Нямало толкова голяма фен база... Все… see more LIKE PRAISE EMPATHY 1,697 ·12 Comments Read more Read more
Tsvetomir Banovski
Tsvetomir Banovski
celebrated this
Alexander Semov / Александър Семов Alexander Semov / Александър Семов 1ˢᵗ on LinkedIn Bulgaria for Workplace Well-Being &…
Follow
Много често чувах от хората, че няма да успее, защото няма пари... Нямало толкова голяма фен база... Все…
see more
see more
1,697
·
12 Comments
Read more
Read more
Kiril Dragomirov Kiril Dragomirov loved this Margarita Petrova Margarita Petrova HR Specialist at AXSMarine 🛥️ | Talent Acquisition |… Follow Честит 1 май – Международен ден на труда! 🛠️ 📈 Днес отбелязваме силата на усилията, постоянството и… see more LIKE PRAISE EMPATHY 21 Read more Read more
Kiril Dragomirov
Kiril Dragomirov
loved this
Margarita Petrova Margarita Petrova HR Specialist at AXSMarine 🛥️ | Talent Acquisition |…
Follow
Честит 1 май – Международен ден на труда!
Днес отбелязваме силата на усилията, постоянството и…
see more
see more
21
Read more
Read more
John Pourdanis John Pourdanis 🤷🏼 Professional Nothing Knower | Quality Engineering… Follow
John Pourdanis John Pourdanis 🤷🏼 Professional Nothing Knower | Quality Engineering…
John Pourdanis
Professional Nothing Knower | Quality Engineering…
Follow
...
[Message clipped]
View entire message
View entire message
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":"Vesselin Petrunov - Software Еngineering Manager reacted to this post: Забелязвам една плашеща… - 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":"Vesselin Petrunov - Software Еngineering Manager reacted to this post: Забелязвам една плашеща… - kovaliklukas@gmail.com - Gmail","depth":5,"bounds":{"left":0.34408244,"top":0.4301676,"width":0.2372008,"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 21 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":"21","depth":16,"bounds":{"left":0.51745343,"top":0.15841979,"width":0.004155585,"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 8784 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,784","depth":16,"bounds":{"left":0.5119681,"top":0.31165203,"width":0.009640957,"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":"22","depth":11,"bounds":{"left":0.8859708,"top":0.12330407,"width":0.004155585,"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":"Vesselin Petrunov - Software Еngineering Manager reacted to this post: Забелязвам една плашеща…","depth":13,"bounds":{"left":0.55352396,"top":0.16440542,"width":0.3394282,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Vesselin Petrunov - Software Еngineering Manager reacted to this post: Забелязвам една плашеща…","depth":14,"bounds":{"left":0.55352396,"top":0.16440542,"width":0.33610374,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Important according to Google magic","depth":14,"bounds":{"left":0.88962764,"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.90292555,"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.9147274,"top":0.16839585,"width":0.004986702,"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":"LinkedIn Verified sender updates-noreply@linkedin.com Unsubscribe","depth":23,"bounds":{"left":0.55352396,"top":0.20271349,"width":0.12765957,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXCell","text":"LinkedIn Verified sender updates-noreply@linkedin.com","depth":24,"bounds":{"left":0.55352396,"top":0.2047087,"width":0.08959442,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"LinkedIn","depth":25,"bounds":{"left":0.55352396,"top":0.20351157,"width":0.019281914,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Verified sender","depth":25,"bounds":{"left":0.5739694,"top":0.2047087,"width":0.007978723,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"updates-noreply@linkedin.com","depth":25,"bounds":{"left":0.58394283,"top":0.2047087,"width":0.05618351,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Unsubscribe","depth":25,"bounds":{"left":0.64577794,"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.6497673,"top":0.20351157,"width":0.027426861,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Wed 6 May, 19:47 (3 days ago)","depth":20,"bounds":{"left":0.8502327,"top":0.20271349,"width":0.05435505,"height":0.015961692},"on_screen":true,"help_text":"6 May 2026, 19:47","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Wed 6 May, 19:47 (3 days ago)","depth":21,"bounds":{"left":0.8502327,"top":0.2047087,"width":0.05435505,"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":21,"bounds":{"left":0.55352396,"top":0.2490024,"width":0.024933511,"height":0.043894652},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏","depth":21,"bounds":{"left":0.55352396,"top":0.26456505,"width":0.011801862,"height":0.2462091},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LinkedIn","depth":23,"bounds":{"left":0.67852396,"top":0.26656026,"width":0.027925532,"height":0.033519555},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Messaging icon","depth":24,"bounds":{"left":0.7918883,"top":0.27134877,"width":0.010305851,"height":0.019952115},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Mynetwork icon","depth":24,"bounds":{"left":0.80485374,"top":0.27134877,"width":0.010638298,"height":0.019952115},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Notifications icon","depth":24,"bounds":{"left":0.8181516,"top":0.27134877,"width":0.013297873,"height":0.019952115},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Vesselin Petrunov Vesselin Petrunov liked this Shule Y. Shule Y. Founder & Strategic Architect @ Tech Bridge |… Follow Забелязвам една плашеща тенденция, че всеки втори е експерт по ИИ… Едно е да използваш ИИ като потребител в… see more LIKE PRAISE INTEREST 61 ·57 Comments Read more","depth":23,"bounds":{"left":0.67852396,"top":0.33838788,"width":0.15425532,"height":0.22905028},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Vesselin Petrunov","depth":27,"bounds":{"left":0.68650264,"top":0.339585,"width":0.040059842,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Vesselin Petrunov","depth":28,"bounds":{"left":0.68650264,"top":0.339585,"width":0.040059842,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"liked this","depth":27,"bounds":{"left":0.7265625,"top":0.339585,"width":0.02044548,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Shule Y. Shule Y. Founder & Strategic Architect @ Tech Bridge |…","depth":27,"bounds":{"left":0.67852396,"top":0.37390262,"width":0.12765957,"height":0.042298485},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Follow","depth":28,"bounds":{"left":0.8068484,"top":0.38228253,"width":0.025265958,"height":0.025139665},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Забелязвам една плашеща тенденция, че всеки втори е експерт по ИИ… Едно е да използваш ИИ като потребител в…","depth":27,"bounds":{"left":0.67852396,"top":0.4293695,"width":0.14893617,"height":0.04708699},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"see more","depth":27,"bounds":{"left":0.6868351,"top":0.46089387,"width":0.023271276,"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":"see more","depth":28,"bounds":{"left":0.6868351,"top":0.4612929,"width":0.023271276,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"61","depth":28,"bounds":{"left":0.6984708,"top":0.490423,"width":0.004986702,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"·","depth":28,"bounds":{"left":0.70478725,"top":0.49082202,"width":0.0013297872,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"57 Comments","depth":28,"bounds":{"left":0.7074468,"top":0.490423,"width":0.029920213,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Read more","depth":26,"bounds":{"left":0.67852396,"top":0.53072625,"width":0.15425532,"height":0.03671189},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Nikolay Yankov Nikolay Yankov liked this Mollie Luckhurst Mollie Luckhurst Strategic Operator | Scaling SaaS Businesses | CS… Follow I don’t think I’ve bought my own laptop in about 20 years. It’s always been work-issued or the occasional… see more LIKE PRAISE EMPATHY 69 ·13 Comments Read more Read more","depth":23,"bounds":{"left":0.67852396,"top":0.6101357,"width":0.15425532,"height":0.38986433},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Nikolay Yankov","depth":27,"bounds":{"left":0.68650264,"top":0.6113328,"width":0.03374335,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Nikolay Yankov","depth":28,"bounds":{"left":0.68650264,"top":0.6117318,"width":0.03374335,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"liked this","depth":27,"bounds":{"left":0.720246,"top":0.6117318,"width":0.02044548,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Mollie Luckhurst Mollie Luckhurst Strategic Operator | Scaling SaaS Businesses | CS…","depth":27,"bounds":{"left":0.67852396,"top":0.6460495,"width":0.12765957,"height":0.041899443},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Follow","depth":28,"bounds":{"left":0.8068484,"top":0.6544294,"width":0.025265958,"height":0.025139665},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"I don’t think I’ve bought my own laptop in about 20 years. It’s always been work-issued or the occasional…","depth":27,"bounds":{"left":0.67852396,"top":0.70111734,"width":0.14727394,"height":0.0311253},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"see more","depth":27,"bounds":{"left":0.7875665,"top":0.71668,"width":0.023271276,"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":"see more","depth":28,"bounds":{"left":0.7875665,"top":0.717079,"width":0.023271276,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"69","depth":28,"bounds":{"left":0.6984708,"top":0.74660814,"width":0.005817819,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"·","depth":28,"bounds":{"left":0.7056183,"top":0.7470072,"width":0.0013297872,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13 Comments","depth":28,"bounds":{"left":0.70827794,"top":0.74660814,"width":0.029421542,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Read more","depth":28,"bounds":{"left":0.67852396,"top":0.77374303,"width":0.15359043,"height":0.20510775},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Read more","depth":26,"bounds":{"left":0.67852396,"top":1.0,"width":0.15425532,"height":-0.0079808235},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Tsvetomir Banovski Tsvetomir Banovski celebrated this Alexander Semov / Александър Семов Alexander Semov / Александър Семов 1ˢᵗ on LinkedIn Bulgaria for Workplace Well-Being &… Follow Много често чувах от хората, че няма да успее, защото няма пари... Нямало толкова голяма фен база... Все… see more LIKE PRAISE EMPATHY 1,697 ·12 Comments Read more Read more","depth":23,"bounds":{"left":0.67852396,"top":1.0,"width":0.15425532,"height":-0.0877893},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Tsvetomir Banovski","depth":27,"bounds":{"left":0.68650264,"top":1.0,"width":0.043550532,"height":-0.0889864},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Tsvetomir Banovski","depth":28,"bounds":{"left":0.68650264,"top":1.0,"width":0.043550532,"height":-0.0889864},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"celebrated this","depth":27,"bounds":{"left":0.7300532,"top":1.0,"width":0.033410903,"height":-0.0889864},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Alexander Semov / Александър Семов Alexander Semov / Александър Семов 1ˢᵗ on LinkedIn Bulgaria for Workplace Well-Being &…","depth":27,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Follow","depth":28,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Много често чувах от хората, че няма да успее, защото няма пари... Нямало толкова голяма фен база... Все…","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"see more","depth":27,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"see more","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1,697","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"·","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12 Comments","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Read more","depth":28,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Read more","depth":26,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Kiril Dragomirov Kiril Dragomirov loved this Margarita Petrova Margarita Petrova HR Specialist at AXSMarine 🛥️ | Talent Acquisition |… Follow Честит 1 май – Международен ден на труда! 🛠️ 📈 Днес отбелязваме силата на усилията, постоянството и… see more LIKE PRAISE EMPATHY 21 Read more Read more","depth":23,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Kiril Dragomirov","depth":27,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Kiril Dragomirov","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"loved this","depth":27,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Margarita Petrova Margarita Petrova HR Specialist at AXSMarine 🛥️ | Talent Acquisition |…","depth":27,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Follow","depth":28,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Честит 1 май – Международен ден на труда!","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":"AXLink","text":"see more","depth":27,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"see more","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Read more","depth":28,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Read more","depth":26,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"John Pourdanis John Pourdanis 🤷🏼 Professional Nothing Knower | Quality Engineering… Follow","depth":23,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"John Pourdanis John Pourdanis 🤷🏼 Professional Nothing Knower | Quality Engineering…","depth":26,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"John Pourdanis","depth":29,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Professional Nothing Knower | Quality Engineering…","depth":29,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Follow","depth":27,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"...","depth":21,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[Message clipped]","depth":21,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"View entire message","depth":21,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"View entire message","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Reply","depth":14,"bounds":{"left":0.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}]...
|
2779740006160741385
|
-9171883464535172399
|
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
Vesselin Petrunov - Software Еngineering Manager reacted to this post: Забелязвам една плашеща… - [EMAIL] - Gmail
Vesselin Petrunov - Software Еngineering Manager reacted to this post: Забелязвам една плашеща… - [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 21 unread
Inbox
21
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 8784 unread has menu
Updates
8,784
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
22
of
21,245
Newer
Older
Input tools on/off (Ctrl-Shift-K)
Select input tool
Print all
In new window
Vesselin Petrunov - Software Еngineering Manager reacted to this post: Забелязвам една плашеща…
Vesselin Petrunov - Software Еngineering Manager reacted to this post: Забелязвам една плашеща…
Important according to Google magic
Search for all messages with label Inbox
Remove label Inbox from this conversation
LinkedIn Verified sender [EMAIL] Unsubscribe
LinkedIn Verified sender [EMAIL]
LinkedIn
Verified sender
[EMAIL]
Unsubscribe
Unsubscribe
Wed 6 May, 19:47 (3 days ago)
Wed 6 May, 19:47 (3 days ago)
Not starred
You can't react to a group with an emoji
Reply
More message options
to
me
Show details
Забелязвам една плашеща…
͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏
LinkedIn
Messaging icon
Mynetwork icon
Notifications icon
Vesselin Petrunov Vesselin Petrunov liked this Shule Y. Shule Y. Founder & Strategic Architect @ Tech Bridge |… Follow Забелязвам една плашеща тенденция, че всеки втори е експерт по ИИ… Едно е да използваш ИИ като потребител в… see more LIKE PRAISE INTEREST 61 ·57 Comments Read more
Vesselin Petrunov
Vesselin Petrunov
liked this
Shule Y. Shule Y. Founder & Strategic Architect @ Tech Bridge |…
Follow
Забелязвам една плашеща тенденция, че всеки втори е експерт по ИИ… Едно е да използваш ИИ като потребител в…
see more
see more
61
·
57 Comments
Read more
Nikolay Yankov Nikolay Yankov liked this Mollie Luckhurst Mollie Luckhurst Strategic Operator | Scaling SaaS Businesses | CS… Follow I don’t think I’ve bought my own laptop in about 20 years. It’s always been work-issued or the occasional… see more LIKE PRAISE EMPATHY 69 ·13 Comments Read more Read more
Nikolay Yankov
Nikolay Yankov
liked this
Mollie Luckhurst Mollie Luckhurst Strategic Operator | Scaling SaaS Businesses | CS…
Follow
I don’t think I’ve bought my own laptop in about 20 years. It’s always been work-issued or the occasional…
see more
see more
69
·
13 Comments
Read more
Read more
Tsvetomir Banovski Tsvetomir Banovski celebrated this Alexander Semov / Александър Семов Alexander Semov / Александър Семов 1ˢᵗ on LinkedIn Bulgaria for Workplace Well-Being &… Follow Много често чувах от хората, че няма да успее, защото няма пари... Нямало толкова голяма фен база... Все… see more LIKE PRAISE EMPATHY 1,697 ·12 Comments Read more Read more
Tsvetomir Banovski
Tsvetomir Banovski
celebrated this
Alexander Semov / Александър Семов Alexander Semov / Александър Семов 1ˢᵗ on LinkedIn Bulgaria for Workplace Well-Being &…
Follow
Много често чувах от хората, че няма да успее, защото няма пари... Нямало толкова голяма фен база... Все…
see more
see more
1,697
·
12 Comments
Read more
Read more
Kiril Dragomirov Kiril Dragomirov loved this Margarita Petrova Margarita Petrova HR Specialist at AXSMarine 🛥️ | Talent Acquisition |… Follow Честит 1 май – Международен ден на труда! 🛠️ 📈 Днес отбелязваме силата на усилията, постоянството и… see more LIKE PRAISE EMPATHY 21 Read more Read more
Kiril Dragomirov
Kiril Dragomirov
loved this
Margarita Petrova Margarita Petrova HR Specialist at AXSMarine 🛥️ | Talent Acquisition |…
Follow
Честит 1 май – Международен ден на труда!
Днес отбелязваме силата на усилията, постоянството и…
see more
see more
21
Read more
Read more
John Pourdanis John Pourdanis 🤷🏼 Professional Nothing Knower | Quality Engineering… Follow
John Pourdanis John Pourdanis 🤷🏼 Professional Nothing Knower | Quality Engineering…
John Pourdanis
Professional Nothing Knower | Quality Engineering…
Follow
...
[Message clipped]
View entire message
View entire message
Reply
Reply
Forward
Forward
You can't react to a group with an emoji
Calendar
Keep
Tasks
Contacts
Get add-ons
Hide side panel...
|
12349
|
NULL
|
NULL
|
NULL
|
|
13884
|
620
|
40
|
2026-05-09T16:38:11.243646+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778344691243_m2.jpg...
|
Firefox
|
Providers - Admin - authentik — Personal
|
True
|
auth.lakylak.xyz/if/admin/#/core/providers
|
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
Електронно банкиране ДСК Директ от Банка ДСК
Close tab
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
Close tab
VIVACOM
Close tab
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
Close tab
VIVACOM
Close tab
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
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
Providers - Admin - authentik
Close tab
New Tab
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Customize sidebar
Skip to content
Home
Providers
Provide support for protocols like SAML and OAuth to assigned applications.
Provide support for protocols like SAML and OAuth to assigned applications.
Toggle API requests drawer
Toggle notifications drawer
0
unread
Settings
Sign out
User interface
User interface
Dashboards
Collapse Dashboards
Dashboards
Overview
Overview
User Statistics
User Statistics
System Tasks
System Tasks
Applications
Collapse Applications
Applications
Applications
Applications
Providers
Providers
Outposts
Outposts
Endpoint Devices
Expand Endpoint Devices
Endpoint Devices
Events
Expand Events
Events
Customization
Expand Customization
Customization
Flows and Stages
Expand Flows and Stages
Flows and Stages
Directory
Expand Directory
Directory
System
Expand System
System
Enterprise
Expand Enterprise
Enterprise
Product name
authentik
Product version
Version 2026.2.1
Select all rows on page (0 of 3 selected)
Name
Sort by "Name"
Name
Application
Application
Type
Type
Row Actions
Actions
Select "Reminders Proxy" row
Reminders Proxy
Reminders Proxy
Assigned to application
Reminders
Reminders
Proxy Provider
Edit "Reminders Proxy" provider
Select "open-webui" row
open-webui
open-webui
Assigned to application
Open WebUI
Open WebUI
OAuth2/OpenID Provider
Edit "open-webui" provider
Select "reminders-mcp" row
reminders-mcp
reminders-mcp
Assigned to application
Reminders MCP
Reminders MCP
OAuth2/OpenID Provider
Edit "reminders-mcp" provider
Name
Sort by "Name"
Name
Reminders Proxy
Reminders Proxy
open-webui
open-webui
reminders-mcp
reminders-mcp
Application
Application
Assigned to application
Reminders
Reminders
Assigned to application
Open WebUI
Open WebUI
Assigned to application
Reminders MCP
Reminders MCP
Type
Type
Proxy Provider
OAuth2/OpenID Provider
OAuth2/OpenID Provider
Row Actions
Actions
Edit "Reminders Proxy" provider
Edit "open-webui" provider
Edit "reminders-mcp" provider
Last refreshed
35 seconds ago
1 - 3 of 3
1 - 3 of 3
Go to previous page
Go to next page
Close sidebar
default-provider-authorization-explicit-consent (Authorize Application) default-provider-authorization-explicit-consent
default-provider-authorization-explicit-consent (Authorize Application) default-provider-authorization-explicit-consent
default-provider-authorization-explicit-consent (Authorize Application)
default-provider-authorization-explicit-consent
default-provider-authorization-implicit-consent (Authorize Application) default-provider-authorization-implicit-consent
default-provider-authorization-implicit-consent (Authorize Application) default-provider-authorization-implicit-consent
default-provider-authorization-implicit-consent (Authorize Application)
default-provider-authorization-implicit-consent...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Pull requests · screenpipe/screenpipe · GitHub","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.016123671,"height":0.032721467},"on_screen":false,"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.0,"width":0.004986702,"height":0.011971269},"on_screen":false,"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.0,"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.0,"width":0.004986702,"height":0.011971269},"on_screen":false,"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.028332002,"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.028332002,"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.061053474,"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.061053474,"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.09377494,"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.09377494,"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.1264964,"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.1264964,"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.15921788,"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.15921788,"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.19193934,"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.19193934,"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.22466081,"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.22466081,"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.25738227,"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.25738227,"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.29010376,"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.29010376,"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.32282522,"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.32282522,"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.35554668,"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.35554668,"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.38826814,"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.38826814,"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.42098963,"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.42098963,"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.4537111,"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.4537111,"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":"Електронно банкиране ДСК Директ от Банка ДСК","depth":4,"bounds":{"left":0.0,"top":0.48643255,"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.48643255,"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":"Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE","depth":4,"bounds":{"left":0.0,"top":0.519154,"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.519154,"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":"VIVACOM","depth":4,"bounds":{"left":0.0,"top":0.5518755,"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.5518755,"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":"Смартфони с Unlimited план до 120 € отстъпка | Vivacom","depth":4,"bounds":{"left":0.0,"top":0.584597,"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.584597,"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":"VIVACOM","depth":4,"bounds":{"left":0.0,"top":0.61731845,"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.61731845,"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":"Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom","depth":4,"bounds":{"left":0.0,"top":0.6500399,"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.6500399,"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.6827614,"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.6827614,"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.71548283,"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.71548283,"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.7482043,"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.7482043,"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":"Providers - Admin - authentik","depth":4,"bounds":{"left":0.0,"top":0.78092575,"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.78092575,"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.81803674,"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":"AXButton","text":"Skip to content","depth":6,"bounds":{"left":0.016123671,"top":0.0518755,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Home","depth":8,"bounds":{"left":0.025099734,"top":0.08539505,"width":0.078457445,"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":"Providers","depth":10,"bounds":{"left":0.13547207,"top":0.075019956,"width":0.03474069,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Provide support for protocols like SAML and OAuth to assigned applications.","depth":8,"bounds":{"left":0.123171546,"top":0.1009577,"width":0.2330452,"height":0.033519555},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Provide support for protocols like SAML and OAuth to assigned applications.","depth":10,"bounds":{"left":0.123171546,"top":0.10574621,"width":0.18018617,"height":0.01715882},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Toggle API requests drawer","depth":10,"bounds":{"left":0.3615359,"top":0.08539505,"width":0.017287234,"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 notifications drawer","depth":10,"bounds":{"left":0.37882313,"top":0.08539505,"width":0.02144282,"height":0.028731046},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0","depth":13,"bounds":{"left":0.39145613,"top":0.09098165,"width":0.0034906915,"height":0.01715882},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"unread","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":10,"bounds":{"left":0.40026596,"top":0.08539505,"width":0.015957447,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Sign out","depth":10,"bounds":{"left":0.4162234,"top":0.08539505,"width":0.015957447,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"User interface","depth":9,"bounds":{"left":0.43218085,"top":0.086592175,"width":0.039893616,"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":"User interface","depth":10,"bounds":{"left":0.4375,"top":0.09217877,"width":0.02925532,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Dashboards","depth":8,"bounds":{"left":0.017121011,"top":0.15403032,"width":0.09541223,"height":0.1300878},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse Dashboards","depth":9,"bounds":{"left":0.017121011,"top":0.15403032,"width":0.09541223,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Dashboards","depth":10,"bounds":{"left":0.02244016,"top":0.16161214,"width":0.02825798,"height":0.01715882},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Overview","depth":12,"bounds":{"left":0.023603724,"top":0.18914606,"width":0.08892952,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Overview","depth":13,"bounds":{"left":0.028922873,"top":0.1963288,"width":0.019448139,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Statistics","depth":12,"bounds":{"left":0.023603724,"top":0.21867518,"width":0.08892952,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Statistics","depth":13,"bounds":{"left":0.028922873,"top":0.22585794,"width":0.029920213,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"System Tasks","depth":12,"bounds":{"left":0.023603724,"top":0.2482043,"width":0.08892952,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"System Tasks","depth":13,"bounds":{"left":0.028922873,"top":0.25538707,"width":0.027759308,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Applications","depth":8,"bounds":{"left":0.017121011,"top":0.28411812,"width":0.09541223,"height":0.1300878},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse Applications","depth":9,"bounds":{"left":0.017121011,"top":0.28411812,"width":0.09541223,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Applications","depth":10,"bounds":{"left":0.02244016,"top":0.29169992,"width":0.02925532,"height":0.01715882},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Applications","depth":12,"bounds":{"left":0.023603724,"top":0.31923383,"width":0.08892952,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Applications","depth":13,"bounds":{"left":0.028922873,"top":0.3264166,"width":0.02543218,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Providers","depth":12,"bounds":{"left":0.023603724,"top":0.34876296,"width":0.08892952,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Providers","depth":13,"bounds":{"left":0.028922873,"top":0.35594574,"width":0.019448139,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Outposts","depth":12,"bounds":{"left":0.023603724,"top":0.3782921,"width":0.08892952,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Outposts","depth":13,"bounds":{"left":0.028922873,"top":0.38547486,"width":0.019448139,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Endpoint Devices","depth":8,"bounds":{"left":0.017121011,"top":0.4142059,"width":0.09541223,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Expand Endpoint Devices","depth":9,"bounds":{"left":0.017121011,"top":0.4142059,"width":0.09541223,"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":"AXStaticText","text":"Endpoint Devices","depth":10,"bounds":{"left":0.02244016,"top":0.4217877,"width":0.04155585,"height":0.01715882},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Events","depth":8,"bounds":{"left":0.017121011,"top":0.44932163,"width":0.09541223,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Expand Events","depth":9,"bounds":{"left":0.017121011,"top":0.44932163,"width":0.09541223,"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":"AXStaticText","text":"Events","depth":10,"bounds":{"left":0.02244016,"top":0.45690343,"width":0.016123671,"height":0.01715882},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Customization","depth":8,"bounds":{"left":0.017121011,"top":0.48443735,"width":0.09541223,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Expand Customization","depth":9,"bounds":{"left":0.017121011,"top":0.48443735,"width":0.09541223,"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":"AXStaticText","text":"Customization","depth":10,"bounds":{"left":0.02244016,"top":0.49201915,"width":0.034242023,"height":0.01715882},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Flows and Stages","depth":8,"bounds":{"left":0.017121011,"top":0.51955307,"width":0.09541223,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Expand Flows and Stages","depth":9,"bounds":{"left":0.017121011,"top":0.51955307,"width":0.09541223,"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":"AXStaticText","text":"Flows and Stages","depth":10,"bounds":{"left":0.02244016,"top":0.5271349,"width":0.04138963,"height":0.01715882},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Directory","depth":8,"bounds":{"left":0.017121011,"top":0.5546688,"width":0.09541223,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Expand Directory","depth":9,"bounds":{"left":0.017121011,"top":0.5546688,"width":0.09541223,"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":"AXStaticText","text":"Directory","depth":10,"bounds":{"left":0.02244016,"top":0.5622506,"width":0.022107713,"height":0.01715882},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"System","depth":8,"bounds":{"left":0.017121011,"top":0.5897845,"width":0.09541223,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Expand System","depth":9,"bounds":{"left":0.017121011,"top":0.5897845,"width":0.09541223,"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":"AXStaticText","text":"System","depth":10,"bounds":{"left":0.02244016,"top":0.59736633,"width":0.017785905,"height":0.01715882},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Enterprise","depth":8,"bounds":{"left":0.017121011,"top":0.6249002,"width":0.09541223,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Expand Enterprise","depth":9,"bounds":{"left":0.017121011,"top":0.6249002,"width":0.09541223,"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":"AXStaticText","text":"Enterprise","depth":10,"bounds":{"left":0.02244016,"top":0.63248205,"width":0.024601065,"height":0.01715882},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Product name","depth":8,"bounds":{"left":0.026761968,"top":0.9537111,"width":0.07513298,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"authentik","depth":9,"bounds":{"left":0.056017287,"top":0.9545092,"width":0.01662234,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Product version","depth":8,"bounds":{"left":0.026761968,"top":0.9680766,"width":0.07513298,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Version 2026.2.1","depth":9,"bounds":{"left":0.050033245,"top":0.9688747,"width":0.028590426,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Select all rows on page (0 of 3 selected)","depth":14,"bounds":{"left":0.12849069,"top":0.23463687,"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":"AXCell","text":"Name","depth":13,"bounds":{"left":0.13646941,"top":0.22106944,"width":0.06582447,"height":0.035514764},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXButton","text":"Sort by \"Name\"","depth":14,"bounds":{"left":0.13646941,"top":0.22825219,"width":0.026263298,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Name","depth":16,"bounds":{"left":0.13912898,"top":0.23383878,"width":0.013297873,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Application","depth":13,"bounds":{"left":0.20229389,"top":0.22106944,"width":0.15442154,"height":0.035514764},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Application","depth":14,"bounds":{"left":0.20495346,"top":0.23383878,"width":0.026097074,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Type","depth":13,"bounds":{"left":0.3567154,"top":0.22106944,"width":0.09541223,"height":0.035514764},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Type","depth":14,"bounds":{"left":0.359375,"top":0.23383878,"width":0.011136968,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Row Actions","depth":13,"bounds":{"left":0.45212767,"top":0.22106944,"width":0.039893616,"height":0.035514764},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Actions","depth":14,"bounds":{"left":0.45478722,"top":0.23383878,"width":0.017287234,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Select \"Reminders Proxy\" row","depth":13,"bounds":{"left":0.12849069,"top":0.27214685,"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":"AXLink","text":"Reminders Proxy","depth":13,"bounds":{"left":0.13912898,"top":0.27094972,"width":0.03474069,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Reminders Proxy","depth":14,"bounds":{"left":0.13912898,"top":0.27094972,"width":0.03474069,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Assigned to application","depth":13,"bounds":{"left":0.21060506,"top":0.27094972,"width":0.049534574,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Reminders","depth":13,"bounds":{"left":0.2601396,"top":0.27094972,"width":0.021941489,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Reminders","depth":14,"bounds":{"left":0.2601396,"top":0.27094972,"width":0.021941489,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Proxy Provider","depth":13,"bounds":{"left":0.359375,"top":0.27094972,"width":0.030086435,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Edit \"Reminders Proxy\" provider","depth":14,"bounds":{"left":0.45478722,"top":0.26336792,"width":0.011303191,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Select \"open-webui\" row","depth":13,"bounds":{"left":0.12849069,"top":0.31444532,"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":"AXLink","text":"open-webui","depth":13,"bounds":{"left":0.13912898,"top":0.31324822,"width":0.024767287,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"open-webui","depth":14,"bounds":{"left":0.13912898,"top":0.31324822,"width":0.024767287,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Assigned to application","depth":13,"bounds":{"left":0.21060506,"top":0.31324822,"width":0.049534574,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Open WebUI","depth":13,"bounds":{"left":0.2601396,"top":0.31324822,"width":0.02642952,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Open WebUI","depth":14,"bounds":{"left":0.2601396,"top":0.31324822,"width":0.02642952,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"OAuth2/OpenID Provider","depth":13,"bounds":{"left":0.359375,"top":0.31324822,"width":0.05285904,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Edit \"open-webui\" provider","depth":14,"bounds":{"left":0.45478722,"top":0.3056664,"width":0.011303191,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Select \"reminders-mcp\" row","depth":13,"bounds":{"left":0.12849069,"top":0.3567438,"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":"AXLink","text":"reminders-mcp","depth":13,"bounds":{"left":0.13912898,"top":0.35554668,"width":0.03174867,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"reminders-mcp","depth":14,"bounds":{"left":0.13912898,"top":0.35554668,"width":0.03174867,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Assigned to application","depth":13,"bounds":{"left":0.21060506,"top":0.35554668,"width":0.049534574,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Reminders MCP","depth":13,"bounds":{"left":0.2601396,"top":0.35554668,"width":0.033410903,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Reminders MCP","depth":14,"bounds":{"left":0.2601396,"top":0.35554668,"width":0.033410903,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"OAuth2/OpenID Provider","depth":13,"bounds":{"left":0.359375,"top":0.35554668,"width":0.05285904,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Edit \"reminders-mcp\" provider","depth":14,"bounds":{"left":0.45478722,"top":0.34796488,"width":0.011303191,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCell","text":"Name","depth":12,"bounds":{"left":0.13646941,"top":0.22106944,"width":0.06582447,"height":0.035514764},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXButton","text":"Sort by \"Name\"","depth":13,"bounds":{"left":0.13646941,"top":0.22825219,"width":0.026263298,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Name","depth":15,"bounds":{"left":0.13912898,"top":0.23383878,"width":0.013297873,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Reminders Proxy","depth":13,"bounds":{"left":0.13912898,"top":0.27094972,"width":0.03474069,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Reminders Proxy","depth":14,"bounds":{"left":0.13912898,"top":0.27094972,"width":0.03474069,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"open-webui","depth":13,"bounds":{"left":0.13912898,"top":0.31324822,"width":0.024767287,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"open-webui","depth":14,"bounds":{"left":0.13912898,"top":0.31324822,"width":0.024767287,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"reminders-mcp","depth":13,"bounds":{"left":0.13912898,"top":0.35554668,"width":0.03174867,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"reminders-mcp","depth":14,"bounds":{"left":0.13912898,"top":0.35554668,"width":0.03174867,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Application","depth":12,"bounds":{"left":0.20229389,"top":0.22106944,"width":0.15442154,"height":0.035514764},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Application","depth":13,"bounds":{"left":0.20495346,"top":0.23383878,"width":0.026097074,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Assigned to application","depth":13,"bounds":{"left":0.21060506,"top":0.27094972,"width":0.049534574,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Reminders","depth":13,"bounds":{"left":0.2601396,"top":0.27094972,"width":0.021941489,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Reminders","depth":14,"bounds":{"left":0.2601396,"top":0.27094972,"width":0.021941489,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Assigned to application","depth":13,"bounds":{"left":0.21060506,"top":0.31324822,"width":0.049534574,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Open WebUI","depth":13,"bounds":{"left":0.2601396,"top":0.31324822,"width":0.02642952,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Open WebUI","depth":14,"bounds":{"left":0.2601396,"top":0.31324822,"width":0.02642952,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Assigned to application","depth":13,"bounds":{"left":0.21060506,"top":0.35554668,"width":0.049534574,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Reminders MCP","depth":13,"bounds":{"left":0.2601396,"top":0.35554668,"width":0.033410903,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Reminders MCP","depth":14,"bounds":{"left":0.2601396,"top":0.35554668,"width":0.033410903,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Type","depth":12,"bounds":{"left":0.3567154,"top":0.22106944,"width":0.09541223,"height":0.035514764},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Type","depth":13,"bounds":{"left":0.359375,"top":0.23383878,"width":0.011136968,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Proxy Provider","depth":13,"bounds":{"left":0.359375,"top":0.27094972,"width":0.030086435,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"OAuth2/OpenID Provider","depth":13,"bounds":{"left":0.359375,"top":0.31324822,"width":0.05285904,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"OAuth2/OpenID Provider","depth":13,"bounds":{"left":0.359375,"top":0.35554668,"width":0.05285904,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Row Actions","depth":12,"bounds":{"left":0.45212767,"top":0.22106944,"width":0.039893616,"height":0.035514764},"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Actions","depth":13,"bounds":{"left":0.45478722,"top":0.23383878,"width":0.017287234,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Edit \"Reminders Proxy\" provider","depth":14,"bounds":{"left":0.45478722,"top":0.26336792,"width":0.011303191,"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":"Edit \"open-webui\" provider","depth":14,"bounds":{"left":0.45478722,"top":0.3056664,"width":0.011303191,"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":"Edit \"reminders-mcp\" provider","depth":14,"bounds":{"left":0.45478722,"top":0.34796488,"width":0.011303191,"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":"Last refreshed","depth":13,"bounds":{"left":0.12849069,"top":0.4046289,"width":0.025265958,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"35 seconds ago","depth":13,"bounds":{"left":0.15475398,"top":0.4046289,"width":0.027260639,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1 - 3 of 3","depth":13,"bounds":{"left":0.4424867,"top":0.40343177,"width":0.01761968,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 - 3 of 3","depth":14,"bounds":{"left":0.4424867,"top":0.40343177,"width":0.01761968,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Go to previous page","depth":13,"bounds":{"left":0.46276596,"top":0.39664805,"width":0.007978723,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Go to next page","depth":13,"bounds":{"left":0.47606382,"top":0.39664805,"width":0.007978723,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Close sidebar","depth":6,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"default-provider-authorization-explicit-consent (Authorize Application) default-provider-authorization-explicit-consent","depth":9,"bounds":{"left":0.21825133,"top":0.36552274,"width":0.17985372,"height":0.046288908},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"default-provider-authorization-explicit-consent (Authorize Application) default-provider-authorization-explicit-consent","depth":10,"bounds":{"left":0.21825133,"top":0.36552274,"width":0.17985372,"height":0.046288908},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"default-provider-authorization-explicit-consent (Authorize Application)","depth":12,"bounds":{"left":0.22357048,"top":0.37270552,"width":0.1690492,"height":0.01715882},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"default-provider-authorization-explicit-consent","depth":11,"bounds":{"left":0.22357048,"top":0.3914605,"width":0.08444149,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"default-provider-authorization-implicit-consent (Authorize Application) default-provider-authorization-implicit-consent","depth":9,"bounds":{"left":0.21825133,"top":0.41181165,"width":0.17985372,"height":0.046288908},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"default-provider-authorization-implicit-consent (Authorize Application) default-provider-authorization-implicit-consent","depth":10,"bounds":{"left":0.21825133,"top":0.41181165,"width":0.17985372,"height":0.046288908},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"default-provider-authorization-implicit-consent (Authorize Application)","depth":12,"bounds":{"left":0.22357048,"top":0.41899443,"width":0.16921543,"height":0.01715882},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"default-provider-authorization-implicit-consent","depth":11,"bounds":{"left":0.22357048,"top":0.43774942,"width":0.08460771,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-2326264545890750523
|
-4952550595434408821
|
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
Електронно банкиране ДСК Директ от Банка ДСК
Close tab
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
Close tab
VIVACOM
Close tab
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
Close tab
VIVACOM
Close tab
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
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
Providers - Admin - authentik
Close tab
New Tab
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Customize sidebar
Skip to content
Home
Providers
Provide support for protocols like SAML and OAuth to assigned applications.
Provide support for protocols like SAML and OAuth to assigned applications.
Toggle API requests drawer
Toggle notifications drawer
0
unread
Settings
Sign out
User interface
User interface
Dashboards
Collapse Dashboards
Dashboards
Overview
Overview
User Statistics
User Statistics
System Tasks
System Tasks
Applications
Collapse Applications
Applications
Applications
Applications
Providers
Providers
Outposts
Outposts
Endpoint Devices
Expand Endpoint Devices
Endpoint Devices
Events
Expand Events
Events
Customization
Expand Customization
Customization
Flows and Stages
Expand Flows and Stages
Flows and Stages
Directory
Expand Directory
Directory
System
Expand System
System
Enterprise
Expand Enterprise
Enterprise
Product name
authentik
Product version
Version 2026.2.1
Select all rows on page (0 of 3 selected)
Name
Sort by "Name"
Name
Application
Application
Type
Type
Row Actions
Actions
Select "Reminders Proxy" row
Reminders Proxy
Reminders Proxy
Assigned to application
Reminders
Reminders
Proxy Provider
Edit "Reminders Proxy" provider
Select "open-webui" row
open-webui
open-webui
Assigned to application
Open WebUI
Open WebUI
OAuth2/OpenID Provider
Edit "open-webui" provider
Select "reminders-mcp" row
reminders-mcp
reminders-mcp
Assigned to application
Reminders MCP
Reminders MCP
OAuth2/OpenID Provider
Edit "reminders-mcp" provider
Name
Sort by "Name"
Name
Reminders Proxy
Reminders Proxy
open-webui
open-webui
reminders-mcp
reminders-mcp
Application
Application
Assigned to application
Reminders
Reminders
Assigned to application
Open WebUI
Open WebUI
Assigned to application
Reminders MCP
Reminders MCP
Type
Type
Proxy Provider
OAuth2/OpenID Provider
OAuth2/OpenID Provider
Row Actions
Actions
Edit "Reminders Proxy" provider
Edit "open-webui" provider
Edit "reminders-mcp" provider
Last refreshed
35 seconds ago
1 - 3 of 3
1 - 3 of 3
Go to previous page
Go to next page
Close sidebar
default-provider-authorization-explicit-consent (Authorize Application) default-provider-authorization-explicit-consent
default-provider-authorization-explicit-consent (Authorize Application) default-provider-authorization-explicit-consent
default-provider-authorization-explicit-consent (Authorize Application)
default-provider-authorization-explicit-consent
default-provider-authorization-implicit-consent (Authorize Application) default-provider-authorization-implicit-consent
default-provider-authorization-implicit-consent (Authorize Application) default-provider-authorization-implicit-consent
default-provider-authorization-implicit-consent (Authorize Application)
default-provider-authorization-implicit-consent...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
13893
|
619
|
40
|
2026-05-09T16:38:49.621685+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778344729621_m1.jpg...
|
Code
|
Implement Authentik inte… — finance [SSH: nas]
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧ Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧G) - 10 pending changes
10
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
mcp
scripts
.env
.env.example
M
.gitignore
M
docker-compose.yml
M
README.md
sms_export.json
payments-logger
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
docker-compose.yml, Editor Group 1
.env, Editor Group 1
.env.example, preview, Editor Group 1
report(1).csv, Editor Group 1
report(2).csv, Editor Group 1
sms_export.json, Editor Group 1
# ── Database ───────────────────────────────────────────────────────────────────
[ENV_SECRET]
# ── Notifier service ──────────────────────────────────────────────────────────
NOTIFIER_URL=[URL_WITH_CREDENTIALS]
# Secret key — generate with: openssl rand -base64 36
[ENV_SECRET]
# Public URL authentik is reachable at (used for redirects and the outpost)
AUTHENTIK_HOST=[URL_WITH_CREDENTIALS] version 2>/dev/null && node --version
Copy code to clipboard
OUT
Exit code 127
Bash
Verify public path configuration
IN
# Check if the upload endpoints are really public
grep -n 'PUBLIC_PATHS\|upload\|ingest' /volume2/docker/finance/finance-hub/backend/src/auth.js
Copy code to clipboard
OUT
<tool_use_error>Cancelled: parallel tool call Bash(npm view @modelcontextprotocol/sdk versi…) errored</tool_use_error>
Bash
Check node version and MCP SDK latest
IN
node --version 2>/dev/null && python3 -c "import urllib.request; import json; d=json.loads(urllib.request.urlopen('[URL_WITH_CREDENTIALS] "^1.29.0"
},
"engines": {
"node": ">=18"
}
}
Write
server.js
server.js
236 lines
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
const BASE_URL = (process.env.FINANCE_HUB_URL || '[URL_WITH_CREDENTIALS] '^1.29.0'}
Thinking
Thinking
Good. Now let me test the MCP server can at least start and call the health check:
Bash
Smoke test MCP server startup
IN
FINANCE_HUB_URL=http://localhost:3001 [ENV_SECRET] \
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | timeout 5 node server.js 2>/dev/null | head -3 || echo "NODE test (expected timeout on stdin wait)"
Copy code to clipboard
OUT
{"result":{"tools":[{"name":"list_transactions","description":"List finance transactions with optional filters. Returns paginated results including total amount for the filtered set.","inputSchema":{"type":"object","properties":{"page":{"type":"number","description":"Page number (default 1)"},"limit":{"type":"number","description":"Results per page, max 200 (default 50)"},"dateFrom":{"type":"string","description":"Start date YYYY-MM-DD (inclusive)"},"dateTo":{"type":"string","description":"End date YYYY-MM-DD (inclusive)"},"tag":{"type":"string","description":"Filter by tag name"},"recipient":{"type":"string","description":"Substring match on payee name"},"type":{"type":"string","description":"Transaction type: POS | ATM | WALLET"},"source":{"type":"string","description":"Import source: INGEST | UPLOAD"},"search":{"type":"string","description":"Full-text search across rawMessage and recipient"},"hideBalanceAlerts":{"type":"boolean","description":"Exclude balance-notification SMS (default false)"},"sortBy":{"type":"string","description":"Sort field: date | amount | recipient | createdAt"},"sortDir":{"type":"string","description":"asc or desc (default desc)"}}}},{"name":"spending_by_tag","description":"Aggregate spending totals by tag for a date range. Fetches up to 200 transactions and groups them. Good for monthly summaries.","inputSchema":{"type":"object","properties":{"dateFrom":{"type":"string","description":"Start date YYYY-MM-DD"},"dateTo":{"type":"string","description":"End date YYYY-MM-DD"}}}},{"name":"get_transaction","description":"Get a single transaction by its numeric ID.","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"number","description":"Transaction import ID"}}}},{"name":"list_tags","description":"List all available tags with their colors.","inputSchema":{"type":"object","properties":{}}},{"name":"add_tag","description":"Add a tag to a transaction. Creates the tag globally if it does not exist.","inputSchema":{"type":"object","required":["id","name"],"properties":{"id":{"type":"number","description":"Transaction ID"},"name":{"type":"string","description":"Tag name (e.g. \"Groceries\")"},"color":{"type":"string","description":"Hex color (e.g. \"#22c55e\"). Optional — auto-assigned if omitted."}}}},{"name":"remove_tag","description":"Remove a tag from a transaction.","inputSchema":{"type":"object","required":["id","tagId"],"properties":{"id":{"type":"number","description":"Transaction ID"},"tagId":{"type":"number","description":"Tag ID (from list_tags or the transaction object)"}}}},{"name":"health_check","description":"Check Finance Hub backend connectivity and database status.","inputSchema":{"type":"object","properties":{}}}]},"jsonrpc":"2.0","id":1}
Thinking
Thinking
MCP server responds correctly. Now test an actual tool call:
Bash
Test MCP health_check tool against live backend
IN
\
printf '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}\n{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"health_check","arguments":{}}}\n' | \
FINANCE_HUB_URL=http://localhost:3001 [ENV_SECRET] \
timeout 5 node server.js 2>/dev/null | tail -1 | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['result']['content'][0]['text'])"
Copy code to clipboard
OUT
{
"status": "ok",
"timestamp": "2026-05-09T16:19:09.977Z",
"storage": {
"type": "PostgreSQL",
"host": "db",
"database": "finance_hub"
}
}
Bash
Rebuild backend with API key auth changes
IN
# Test the API key auth directly against the backend (backend still has DEV_BYPASS_AUTH=true, need to restart first)
# First rebuild with the new code
cd /volume2/docker/finance/finance-hub && docker compose up -d --build backend 2>&1 | tail -8
Copy code to clipboard
OUT
time="2026-05-09T19:19:13+03:00" level=warning msg="/volume2/docker/finance/finance-hub/docker-compose.yml: `version` is obsolete"
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.45/containers/json?all=1&filters=%7B%22label%22%3A%7B%22com.docker.compose.config-hash%22%3Atrue%2C%22com.docker.compose.project%3Dfinance-hub%22%3Atrue%7D%7D": dial unix /var/run/docker.sock: connect: permission denied
Bash
Rebuild backend with sudo
IN
sudo docker compose -f /volume2/docker/finance/finance-hub/docker-compose.yml up -d --build backend 2>&1 | tail -10
Copy code to clipboard
OUT
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
sudo: a password is required
Thinking
Thinking
Docker needs sudo+password. Let me verify the auth changes are correct by testing the logic directly:
Bash
Unit test the auth middleware logic
IN
node - << 'EOF'
// Simulate the auth middleware logic
const [ENV_SECRET];
process.env.API_KEY = API_KEY;
const { authentikMiddleware } = require('/volume2/docker/finance/finance-hub/backend/src/auth.js');
function testReq(path, headers = {}) {
const res = { status(code) { this.code = code; return this; }, json(body) { return body; } };
const req = { path, headers };
let passed = false;
authentikMiddleware(req, res, () => { passed = true; });
return { passed, code: res.code, user: req.user };
}
// Public path — no auth needed
let r = testReq('/api/health', {});
console.assert(r.passed, 'health should be public');
console.log('✓ /api/health is public');
// Valid API key
r = testReq('/api/payments', { authorization: `Bearer ${API_KEY}` });
console.assert(r.passed, 'valid key should pass');
console.assert(r.user.username === 'api-key', 'api user');
console.log('✓ valid API key passes');
// Wrong API key
r = testReq('/api/payments', { authorization: 'Bearer wrongkey' });
console.assert(!r.passed, 'wrong key should fail');
console.assert(r.code === 401, '401 on bad key');
console.log('✓ wrong API key returns 401');
// No auth + no bypass + no authentik header
process.env.DEV_BYPASS_AUTH = 'false';
r = testReq('/api/payments', {});
console.assert(!r.passed && r.code === 401, 'no creds → 401');
console.log('✓ no credentials returns 401');
// Upload endpoints no longer public
r = testReq('/api/upload/csv', {});
console.assert(!r.passed && r.code === 401, 'upload/csv requires auth');
console.log('✓ /api/upload/csv now requires auth (was public, now fixed)');
// Authentik header pass-through
r = testReq('/api/payments', { 'x-authentik-username': 'lukastest', 'x-authentik-email': '[EMAIL]' });
console.assert(r.passed && r.user.username === 'lukastest', 'authentik header works');
console.log('✓ Authentik X-authentik-username header works');
console.log('\nAll auth tests passed.');
EOF
Copy code to clipboard
OUT
✓ /api/health is public
✓ valid API key passes
✓ wrong API key returns 401
✓ no credentials returns 401
✓ /api/upload/csv now requires auth (was public, now fixed)
✓ Authentik X-authentik-username header works
All auth tests passed.
All auth cases pass. Now test the MCP spending_by_tag tool against the live backend (with DEV_BYPASS_AUTH still on):
Bash
Test spending_by_tag MCP tool against live backend
IN
cd /volume2/docker/finance/finance-hub/mcp && \
printf '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}\n{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"spending_by_tag","arguments":{"dateFrom":"2026-05-01","dateTo":"2026-05-09"}}}\n' | \
FINANCE_HUB_URL=http://localhost:3001 [ENV_SECRET] \
timeout 8 node server.js 2>/dev/null | grep '"id":2' | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['result']['content'][0]['text'][:500])"
Copy code to clipboard
OUT
{
"period": {
"from": "2026-05-01",
"to": "2026-05-09"
},
"totalTransactions": 36,
"breakdown": [
{
"tag": "Bills",
"total": 117.9,
"count": 6
},
{
"tag": "(untagged)",
"total": 1153.87,
"count": 22
}
]
}
MCP tools work correctly against real data. Let me write the Claude desktop config example and the
.gitignore
for the mcp dir:
Write
claude_desktop_config.example.json
claude_desktop_config.example.json
14 lines
{
"_comment": "Add this block to ~/.config/claude/claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json)",
"mcpServers": {
"finance-hub": {
"command": "node",
"args": ["/volume2/docker/finance/finance-hub/mcp/server.js"],
"env": {
"FINANCE_HUB_URL": "http://localhost:3001",
"FINANCE_HUB_API_KEY": "94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c"
}
}
}
}
Write
.gitignore
.gitignore
2 lines
node_modules/
Update Todos
Fix auth.js: add API key support + remove upload endpoints from PUBLIC_PATHS
Update index.js: add CORS origin restriction via env var
Update .env and .env.example with API_KEY variable
Build MCP server (stdio, Claude desktop compatible)
Test: restart backend, verify API key auth and MCP connection
Now let me save relevant project context to memory:
Read
MEMORY.md
MEMORY.md
Write
MEMORY.md
MEMORY.md
4 lines
# Memory Index
- [project_finance_hub.md](project_finance_hub.md) — Finance Hub architecture, auth design, MCP server, API key setup
Write
project_finance_hub.md
project_finance_hub.md
35 lines
---
name: Finance Hub project state
description: Architecture, auth design, API key, MCP server location and tools for the finance-hub project
type: project
---
Finance Hub is a personal finance tracker at `/volume2/docker/finance/finance-hub/`.
**Running services** (as of 2026-05-09):
- Backend: port 3001 (Express/Prisma, PostgreSQL)
- Frontend: port 5175 (React/Vite)
- Adminer: port 8092
- Authentik: port 9100 (auth.lakylak.xyz, tag 2026.2.1)
**Auth design:**
- Production: NPM (Nginx Proxy Manager) + Authentik forward-auth outpost → injects `X-authentik-username` header
- `DEV_BYPASS_AUTH=true` is currently set in `.env` — app runs without real auth
- API key auth added: `Authorization: Bearer <API_KEY>` bypasses Authentik header check (used by MCP/scripts)
- API_KEY in `.env`: `94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c`
**Public endpoints** (no auth): `/api/health`, `/api/payments/ingest`
**Security fix applied (2026-05-09):** Removed `/api/upload/csv` and `/api/upload/preview` from PUBLIC_PATHS — they were incorrectly public.
**MCP server:** `/volume2/docker/finance/finance-hub/mcp/server.js`
- Stdio transport, works with Claude desktop
- Tools: list_transactions, spending_by_tag, get_transaction, list_tags, add_tag, remove_tag, health_check
- Env: FINANCE_HUB_URL, FINANCE_HUB_API_KEY
- Config example: `mcp/claude_desktop_config.example.json`
**To enable real Authentik auth:** Set `DEV_BYPASS_AUTH=false` in `.env`, configure NPM proxy host for finance-hub w...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Explorer (⇧⌘E)","depth":19,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":true},{"role":"AXStaticText","text":"","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Search (⇧⌘F)","depth":19,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Source Control (⌃⇧G) - 10 pending changes","depth":19,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"10","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Run and Debug (⇧⌘D)","depth":19,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Remote Explorer","depth":19,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Extensions (⇧⌘X) - 2 require update","depth":19,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Claude Code","depth":19,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Containers","depth":19,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"EXPLORER","depth":17,"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"EXPLORER","depth":18,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Explorer Section: finance [SSH: nas]","depth":21,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXHeading","text":"Explorer Section: finance [SSH: nas]","depth":22,"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"FINANCE [SSH: NAS]","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"auth","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"dsk-uploader","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"finance-hub","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"frontend","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"mcp","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"scripts","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".env","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".env.example","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"M","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".gitignore","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"M","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"docker-compose.yml","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"M","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"README.md","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"sms_export.json","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"payments-logger","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Outline Section","depth":21,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXHeading","text":"OUTLINE","depth":22,"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"OUTLINE","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Timeline Section","depth":21,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXHeading","text":"TIMELINE","depth":22,"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"TIMELINE","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"docker-compose.yml, Editor Group 1","depth":28,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":".env, Editor Group 1","depth":28,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXRadioButton","text":".env.example, preview, Editor Group 1","depth":28,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"report(1).csv, Editor Group 1","depth":28,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"report(2).csv, Editor Group 1","depth":28,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"sms_export.json, Editor Group 1","depth":28,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":29,"on_screen":true,"role_description":"text"},{"role":"AXTextArea","text":"# ── Database ───────────────────────────────────────────────────────────────────\nDB_PASSWORD=payments_secret\n\n# ── Notifier service ──────────────────────────────────────────────────────────\nNOTIFIER_URL=https://notifier.lakylak.xyz\nNOTIFIER_CHANNEL=viber\nNOTIFY_DEFAULT_PHONE=+359000000000\n\n# ── Timezone ─────────────────────────────────────────────────────────────────\nTZ=Europe/Sofia\n\n# ── API key auth — for MCP server, scripts, iOS shortcuts on protected endpoints ──\n# Generate with: openssl rand -hex 32\nAPI_KEY=94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c\n\n# ── Dev only — set false and configure NPM+Authentik for production ──────────\n# DEV_BYPASS_AUTH=true","depth":28,"on_screen":true,"value":"# ── Database ───────────────────────────────────────────────────────────────────\nDB_PASSWORD=payments_secret\n\n# ── Notifier service ──────────────────────────────────────────────────────────\nNOTIFIER_URL=https://notifier.lakylak.xyz\nNOTIFIER_CHANNEL=viber\nNOTIFY_DEFAULT_PHONE=+359000000000\n\n# ── Timezone ─────────────────────────────────────────────────────────────────\nTZ=Europe/Sofia\n\n# ── API key auth — for MCP server, scripts, iOS shortcuts on protected endpoints ──\n# Generate with: openssl rand -hex 32\nAPI_KEY=94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c\n\n# ── Dev only — set false and configure NPM+Authentik for production ──────────\n# DEV_BYPASS_AUTH=true","role_description":"editor","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"# ── Database ───────────────────────────────────────────────────────────────────\nDB_PASSWORD=payments_secret\n\n# ── Notifier service ──────────────────────────────────────────────────────────\nNOTIFIER_URL=https://notifier.lakylak.xyz\nNOTIFIER_CHANNEL=viber\nNOTIFY_DEFAULT_PHONE=+359000000000\n\n# ── Timezone ─────────────────────────────────────────────────────────────────\nTZ=Europe/Sofia\n\n# ── API key auth — for MCP server, scripts, iOS shortcuts on protected endpoints ──\n# Generate with: openssl rand -hex 32\nAPI_KEY=94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c\n\n# ── Dev only — set false and configure NPM+Authentik for production ──────────\n# DEV_BYPASS_AUTH=true","depth":29,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Design new payment-logge…, Editor Group 2","depth":28,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Implement Authentik inte…, Editor Group 2","depth":28,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXButton","text":"remote SSH: nas","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SSH: nas","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"finance-hub (Git) - main*, Checkout Branch/Tag...","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"main*","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"finance-hub (Git) - Synchronize Changes","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"No Problems","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"No Ports Forwarded","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Notifications","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sign In","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sign In","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Info: Setting up SSH Host nas: Setting up SSH tunnel","depth":12,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Implement Authentik integration with security review","depth":19,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Session history","depth":19,"on_screen":true,"help_text":"Session history","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New session","depth":19,"on_screen":true,"help_text":"New session","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Message actions","depth":24,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"README.md","depth":23,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"README.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"lets work on authentication. I want to be able to connect using authentik. REveiw copy of the project in auth folder. Lets test it and establish security. There should be simple way to reauthorize automatically for api and also there should be claude chat compatible mcp with autorization that si stable. Think about it test it and then provide suggestions","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Thinking","depth":23,"on_screen":false,"role_description":"disclosure triangle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Thinking","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Let me explore the project structure first, particularly the auth folder.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"List finance 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":"find /volume2/docker/finance -type f | head -80 && echo \"---\" && ls /volume2/docker/finance/","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/volume2/docker/finance/payments-logger/.env\n/volume2/docker/finance/payments-logger/.env.example\n/volume2/docker/finance/payments-logger/.gitignore\n/volume2/docker/finance/payments-logger/API.md\n/volume2/docker/finance/payments-logger/README.md\n/volume2/docker/finance/payments-logger/docker-compose.yml\n/volume2/docker/finance/auth/.env\n/volume2/docker/finance/auth/.env.example\n/volume2/docker/finance/auth/README.md\n/volume2/docker/finance/auth/docker-compose.yml\n/volume2/docker/finance/dsk-uploader/.gitignore\n/volume2/docker/finance/dsk-uploader/README.md\n/volume2/docker/finance/dsk-uploader/USAGE.md\n/volume2/docker/finance/dsk-uploader/app.py\n/volume2/docker/finance/dsk-uploader/app_flask.py\n/volume2/docker/finance/dsk-uploader/dskuploader.py\n/volume2/docker/finance/dsk-uploader/requirements.txt\n/volume2/docker/finance/dsk-uploader/.env\n/volume2/docker/finance/dsk-uploader/.env.example\n/volume2/docker/finance/dsk-uploader/Dockerfile\n/volume2/docker/finance/dsk-uploader/docker-compose.yml\n/volume2/docker/finance/dsk-uploader/.dockerignore\n/volume2/docker/finance/finance-hub/.env.example\n/volume2/docker/finance/finance-hub/.gitignore\n/volume2/docker/finance/finance-hub/.env\n/volume2/docker/finance/finance-hub/docker-compose.yml\n/volume2/docker/finance/finance-hub/sms_export.json\n/volume2/docker/finance/finance-hub/README.md\n/volume2/docker/finance/payments-logger/.claude/settings.local.json\n/volume2/docker/finance/payments-logger/backend/.dockerignore\n/volume2/docker/finance/payments-logger/backend/Dockerfile\n/volume2/docker/finance/payments-logger/backend/package.json\n/volume2/docker/finance/finance-hub/backend/package.json\n/volume2/docker/finance/finance-hub/backend/Dockerfile\n/volume2/docker/finance/finance-hub/frontend/package.json\n/volume2/docker/finance/finance-hub/frontend/Dockerfile\n/volume2/docker/finance/finance-hub/frontend/vite.config.js\n/volume2/docker/finance/finance-hub/frontend/tailwind.config.js\n/volume2/docker/finance/finance-hub/frontend/postcss.config.js\n/volume2/docker/finance/finance-hub/frontend/index.html\n/volume2/docker/finance/finance-hub/scripts/reimport_sms.sh\n/volume2/docker/finance/finance-hub/.git/description\n/volume2/docker/finance/finance-hub/.git/HEAD\n/volume2/docker/finance/finance-hub/.git/COMMIT_EDITMSG\n/volume2/docker/finance/finance-hub/.git/index\n/volume2/docker/finance/finance-hub/.git/hooks/post-update.sample\n/volume2/docker/finance/finance-hub/.git/hooks/pre-applypatch.sample\n/volume2/docker/finance/finance-hub/.git/hooks/pre-commit.sample\n/volume2/docker/finance/finance-hub/.git/hooks/applypatch-msg.sample\n/volume2/docker/finance/finance-hub/.git/hooks/pre-rebase.sample\n/volume2/docker/finance/finance-hub/.git/hooks/pre-merge-commit.sample\n/volume2/docker/finance/finance-hub/.git/hooks/update.sample\n/volume2/docker/finance/finance-hub/.git/hooks/pre-push.sample\n/volume2/docker/finance/finance-hub/.git/hooks/push-to-checkout.sample\n/volume2/docker/finance/finance-hub/.git/hooks/prepare-commit-msg.sample\n/volume2/docker/finance/finance-hub/.git/hooks/commit-msg.sample\n/volume2/docker/finance/finance-hub/.git/hooks/pre-receive.sample\n/volume2/docker/finance/finance-hub/.git/hooks/fsmonitor-watchman.sample\n/volume2/docker/finance/finance-hub/.git/logs/HEAD\n/volume2/docker/finance/payments-logger/frontend/.dockerignore\n/volume2/docker/finance/payments-logger/frontend/Dockerfile\n/volume2/docker/finance/payments-logger/frontend/index.html\n/volume2/docker/finance/payments-logger/frontend/package.json\n/volume2/docker/finance/payments-logger/frontend/postcss.config.js\n/volume2/docker/finance/payments-logger/frontend/tailwind.config.js\n/volume2/docker/finance/payments-logger/frontend/vite.config.js\n/volume2/docker/finance/finance-hub/.git/config\n/volume2/docker/finance/payments-logger/auth/.env\n/volume2/docker/finance/payments-logger/auth/.env.example\n/volume2/docker/finance/payments-logger/auth/README.md\n/volume2/docker/finance/auth/auth/.env\n/volume2/docker/finance/auth/auth/.env.example\n/volume2/docker/finance/auth/auth/docker-compose.yml\n/volume2/docker/finance/auth/auth/README.md\n/volume2/docker/finance/dsk-uploader/.git/description\n/volume2/docker/finance/dsk-uploader/.git/packed-refs\n/volume2/docker/finance/dsk-uploader/.git/HEAD\n/volume2/docker/finance/dsk-uploader/.git/FETCH_HEAD\n/volume2/docker/finance/dsk-uploader/.git/index\n/volume2/docker/finance/dsk-uploader/.git/COMMIT_EDITMSG\n---\nauth\ndsk-uploader\nfinance-hub\npayments-logger","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"README.md","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"README.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"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 dive into the auth folder and the existing backend auth setup.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"README.md","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"README.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"docker-compose.yml","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"docker-compose.yml","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read auth env examples and nested auth config","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"cat /volume2/docker/finance/auth/.env.example && echo \"===\" && cat /volume2/docker/finance/auth/auth/.env.example 2>/dev/null && echo \"===\" && cat /volume2/docker/finance/auth/auth/docker-compose.yml 2>/dev/null","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":"# Copy this file to .env and fill in all values before starting\n\n# ── Image versions ───────────────────────────────────────────────────────────\n# Pinned tag applied to server, worker, AND outpost — they must always match.\n# To upgrade: change this one value and run: docker compose pull && docker compose up -d\n# Check releases: https://github.com/goauthentik/authentik/releases\nAUTHENTIK_TAG=2026.2.1\n\n# ── Database ──────────────────────────────────────────────────────────────────\n# Strong password for the PostgreSQL authentik database\n# Used by the postgres container and all authentik services\nPG_PASS=\n\n# ── Authentik core ────────────────────────────────────────────────────────────\n# Cryptographic secret — NEVER share or commit this\n# Generate with: openssl rand -base64 36\nAUTHENTIK_SECRET_KEY=\n\n# Full public HTTPS URL where authentik is reachable\n# Must match the domain you configure in NPM\n# Used for OAuth redirects and by the outpost to contact the server\nAUTHENTIK_HOST=https://auth.lakylak.xyz\n\n# ── Bootstrap (first-start only) ─────────────────────────────────────────────\n# If set, authentik creates this admin account automatically on first boot.\n# You can leave these empty and use the /if/flow/initial-setup/ URL instead.\nAUTHENTIK_BOOTSTRAP_EMAIL=you@example.com\nAUTHENTIK_BOOTSTRAP_PASSWORD=\n\n# ── Outpost ───────────────────────────────────────────────────────────────────\n# Token for the proxy outpost container.\n# Leave as \"placeholder\" on first deploy — the outpost will fail to connect\n# until you create it in the UI and paste the real token here (see README step 6).\nAUTHENTIK_OUTPOST_TOKEN=placeholder\n===\n# Copy this file to .env and fill in all values before starting\n\n# ── Image versions ───────────────────────────────────────────────────────────\n# Pinned tag applied to server, worker, AND outpost — they must always match.\n# To upgrade: change this one value and run: docker compose pull && docker compose up -d\n# Check releases: https://github.com/goauthentik/authentik/releases\nAUTHENTIK_TAG=2026.2.1\n\n# ── Database ──────────────────────────────────────────────────────────────────\n# Strong password for the PostgreSQL authentik database\n# Used by the postgres container and all authentik services\nPG_PASS=\n\n# ── Authentik core ────────────────────────────────────────────────────────────\n# Cryptographic secret — NEVER share or commit this\n# Generate with: openssl rand -base64 36\nAUTHENTIK_SECRET_KEY=\n\n# Full public HTTPS URL where authentik is reachable\n# Must match the domain you configure in NPM\n# Used for OAuth redirects and by the outpost to contact the server\nAUTHENTIK_HOST=https://auth.lakylak.xyz\n\n# ── Bootstrap (first-start only) ─────────────────────────────────────────────\n# If set, authentik creates this admin account automatically on first boot.\n# You can leave these empty and use the /if/flow/initial-setup/ URL instead.\nAUTHENTIK_BOOTSTRAP_EMAIL=you@example.com\nAUTHENTIK_BOOTSTRAP_PASSWORD=\n\n# ── Outpost ───────────────────────────────────────────────────────────────────\n# Token for the proxy outpost container.\n# Leave as \"placeholder\" on first deploy — the outpost will fail to connect\n# until you create it in the UI and paste the real token here (see README step 6).\nAUTHENTIK_OUTPOST_TOKEN=placeholder\n===\nservices:\n\n postgresql:\n image: docker.io/library/postgres:16-alpine\n container_name: Authentik-DB\n hostname: authentik-db\n restart: unless-stopped\n security_opt:\n - no-new-privileges:true\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -d ${POSTGRES_DB:-authentik} -U ${POSTGRES_USER:-authentik}\"]\n interval: 5s\n timeout: 5s\n retries: 5\n environment:\n POSTGRES_PASSWORD: ${PG_PASS}\n POSTGRES_USER: authentik\n POSTGRES_DB: authentik\n volumes:\n - /volume2/docker/auth/db:/var/lib/postgresql/data\n networks:\n - authentik_internal\n\n redis:\n image: docker.io/library/redis:alpine\n container_name: Authentik-REDIS\n hostname: authentik-redis\n restart: unless-stopped\n security_opt:\n - no-new-privileges:true\n healthcheck:\n test: [\"CMD-SHELL\", \"redis-cli ping | grep PONG\"]\n interval: 5s\n timeout: 3s\n retries: 5\n networks:\n - authentik_internal\n\n server:\n image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG}\n container_name: Authentik-Server\n hostname: authentik-server\n restart: unless-stopped\n command: server\n environment:\n AUTHENTIK_REDIS__HOST: authentik-redis\n AUTHENTIK_POSTGRESQL__HOST: authentik-db\n AUTHENTIK_POSTGRESQL__USER: authentik\n AUTHENTIK_POSTGRESQL__NAME: authentik\n AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}\n AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}\n AUTHENTIK_ERROR_REPORTING__ENABLED: \"false\"\n AUTHENTIK_HOST: ${AUTHENTIK_HOST}\n AUTHENTIK_BOOTSTRAP_EMAIL: ${AUTHENTIK_BOOTSTRAP_EMAIL}\n AUTHENTIK_BOOTSTRAP_PASSWORD: ${AUTHENTIK_BOOTSTRAP_PASSWORD}\n ports:\n - \"9100:9000\"\n volumes:\n - /volume2/docker/auth/media:/media\n - /volume2/docker/auth/templates:/templates\n depends_on:\n postgresql:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - authentik_internal\n - proxy\n\n worker:\n image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG}\n container_name: Authentik-Worker\n hostname: authentik-worker\n restart: unless-stopped\n command: worker\n user: root\n environment:\n AUTHENTIK_REDIS__HOST: authentik-redis\n AUTHENTIK_POSTGRESQL__HOST: authentik-db\n AUTHENTIK_POSTGRESQL__USER: authentik\n AUTHENTIK_POSTGRESQL__NAME: authentik\n AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}\n AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}\n volumes:\n - /var/run/docker.sock:/var/run/docker.sock\n - /volume2/docker/auth/media:/media\n - /volume2/docker/auth/certs:/certs\n - /volume2/docker/auth/templates:/templates\n depends_on:\n postgresql:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - authentik_internal\n\n outpost:\n image: ghcr.io/goauthentik/proxy:${AUTHENTIK_TAG}\n container_name: Authentik-Outpost\n hostname: authentik-outpost\n restart: unless-stopped\n environment:\n AUTHENTIK_HOST: ${AUTHENTIK_HOST}\n AUTHENTIK_INSECURE: \"false\"\n AUTHENTIK_TOKEN: ${AUTHENTIK_OUTPOST_TOKEN}\n ports:\n - \"9101:9000\"\n depends_on:\n - server\n networks:\n - authentik_internal\n - proxy\n\nnetworks:\n authentik_internal:\n internal: true\n proxy:\n external: true","depth":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 look at the backend auth code and the current services.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"List backend and frontend source files","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"find /volume2/docker/finance/finance-hub/backend -type f | sort && echo \"===\" && find /volume2/docker/finance/finance-hub/frontend/src -type f | sort 2>/dev/null || find /volume2/docker/finance/finance-hub/frontend -type f | sort","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/volume2/docker/finance/finance-hub/backend/Dockerfile\n/volume2/docker/finance/finance-hub/backend/package.json\n/volume2/docker/finance/finance-hub/backend/prisma/migrations/20260508_init/migration.sql\n/volume2/docker/finance/finance-hub/backend/prisma/migrations/20260509_refactor/migration.sql\n/volume2/docker/finance/finance-hub/backend/prisma/migrations/migration_lock.toml\n/volume2/docker/finance/finance-hub/backend/prisma/schema.prisma\n/volume2/docker/finance/finance-hub/backend/src/auth.js\n/volume2/docker/finance/finance-hub/backend/src/csvParser.js\n/volume2/docker/finance/finance-hub/backend/src/index.js\n/volume2/docker/finance/finance-hub/backend/src/parser.js\n/volume2/docker/finance/finance-hub/backend/src/routes/payments.js\n/volume2/docker/finance/finance-hub/backend/src/routes/upload.js\n/volume2/docker/finance/finance-hub/backend/src/utils/linkTransaction.js\n/volume2/docker/finance/finance-hub/backend/src/utils/recipientTags.js\n===\n/volume2/docker/finance/finance-hub/frontend/src/App.jsx\n/volume2/docker/finance/finance-hub/frontend/src/components/FilterBar.jsx\n/volume2/docker/finance/finance-hub/frontend/src/components/PaymentCard.jsx\n/volume2/docker/finance/finance-hub/frontend/src/components/PaymentList.jsx\n/volume2/docker/finance/finance-hub/frontend/src/components/PaymentTable.jsx\n/volume2/docker/finance/finance-hub/frontend/src/components/SettingsPanel.jsx\n/volume2/docker/finance/finance-hub/frontend/src/components/UploadPanel.jsx\n/volume2/docker/finance/finance-hub/frontend/src/hooks/useSettings.js\n/volume2/docker/finance/finance-hub/frontend/src/index.css\n/volume2/docker/finance/finance-hub/frontend/src/main.jsx","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Check running Docker containers","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"docker ps --format \"table {{.Names}}\\t{{.Status}}\\t{{.Ports}}\" 2>/dev/null | head -30","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(Bash completed with no output)","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"auth.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"auth.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"index.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"index.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Check all Docker containers","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"docker ps -a --format \"table {{.Names}}\\t{{.Status}}\\t{{.Ports}}\" 2>/dev/null","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":"Exit code 1","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":".env","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":".env","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":".env","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":".env","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"docker-compose.yml","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"docker-compose.yml","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Thinking","depth":23,"on_screen":false,"role_description":"disclosure triangle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Thinking","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"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":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Check status of auth and finance-hub Docker services","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"cd /volume2/docker/finance/auth && docker compose ps 2>/dev/null || echo \"NOT RUNNING\"\necho \"===\"\ncd /volume2/docker/finance/finance-hub && docker compose ps 2>/dev/null || echo \"NOT RUNNING\"","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":"NOT RUNNING\n===\nNOT RUNNING","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":"Let me check a few more details before forming recommendations.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"README.md","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"README.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Check payments-logger auth config","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"cat /volume2/docker/finance/payments-logger/auth/.env.example 2>/dev/null && echo \"===\" && cat /volume2/docker/finance/payments-logger/auth/.env 2>/dev/null","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":"# Copy this file to .env and fill in all values before starting\n\n# ── Image versions ───────────────────────────────────────────────────────────\n# Pinned tag applied to server, worker, AND outpost — they must always match.\n# To upgrade: change this one value and run: docker compose pull && docker compose up -d\n# Check releases: https://github.com/goauthentik/authentik/releases\nAUTHENTIK_TAG=2026.2.1\n\n# ── Database ──────────────────────────────────────────────────────────────────\n# Strong password for the PostgreSQL authentik database\n# Used by the postgres container and all authentik services\nPG_PASS=\n\n# ── Authentik core ────────────────────────────────────────────────────────────\n# Cryptographic secret — NEVER share or commit this\n# Generate with: openssl rand -base64 36\nAUTHENTIK_SECRET_KEY=\n\n# Full public HTTPS URL where authentik is reachable\n# Must match the domain you configure in NPM\n# Used for OAuth redirects and by the outpost to contact the server\nAUTHENTIK_HOST=https://auth.lakylak.xyz\n\n# ── Bootstrap (first-start only) ─────────────────────────────────────────────\n# If set, authentik creates this admin account automatically on first boot.\n# You can leave these empty and use the /if/flow/initial-setup/ URL instead.\nAUTHENTIK_BOOTSTRAP_EMAIL=you@example.com\nAUTHENTIK_BOOTSTRAP_PASSWORD=\n\n# ── Outpost ───────────────────────────────────────────────────────────────────\n# Token for the proxy outpost container.\n# Leave as \"placeholder\" on first deploy — the outpost will fail to connect\n# until you create it in the UI and paste the real token here (see README step 6).\nAUTHENTIK_OUTPOST_TOKEN=placeholder\n===\n# Authentik image tag — applies to server, worker, AND outpost (must all match)\n# Check latest: https://github.com/goauthentik/authentik/releases\n# Example: 2024.12.3\nAUTHENTIK_TAG=2026.2.1\n\n# PostgreSQL password — used by both postgres and authentik server/worker\nPG_PASS=Og8L5@a1QA6u\n\n# Secret key — generate with: openssl rand -base64 36\nAUTHENTIK_SECRET_KEY=Uq6Mc2oI6zeWtoZcCy+Dw+IdNJ80yIMZk5ZgsP/tYmopFmhB/RHxbN7TNFZDNR1wrao=\n\n# Public URL authentik is reachable at (used for redirects and the outpost)\nAUTHENTIK_HOST=https://auth.lakylak.xyz\n\n# Bootstrap admin account created on first start (can be left empty to set via UI)\nAUTHENTIK_BOOTSTRAP_EMAIL=kovaliklukas@proton.me\nAUTHENTIK_BOOTSTRAP_PASSWORD=3bAc4Jcs\n\n# Outpost token — leave as placeholder until you create the outpost in the Authentik UI\n# See README.md step 6 for how to get this value\nAUTHENTIK_OUTPOST_TOKEN=H7Ppl2ps6h6e1mJ0CwXXoklQScbFJ1gT5WYXErtaRRQz5ukWfES78OXLVz6S","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Test if Authentik and finance backend are reachable","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"curl -s --max-time 3 http://localhost:9100/api/v3/core/applications/ 2>/dev/null | head -20 || echo \"Authentik not reachable on 9100\"\ncurl -s --max-time 3 http://localhost:3001/api/health 2>/dev/null | head -5 || echo \"Finance backend not reachable on 3001\"","depth":26,"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":"{\"detail\":\"Authentication credentials were not provided.\"}{\"status\":\"ok\",\"timestamp\":\"2026-05-09T16:02:54.094Z\",\"storage\":{\"type\":\"PostgreSQL\",\"host\":\"db\",\"database\":\"finance_hub\"}}","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":"Both Authentik (port 9100) and finance backend (port 3001) are running. Let me test the actual auth state and check CORS config.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Test backend auth bypass and Authentik health","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# Test that backend accepts requests without auth (DEV_BYPASS_AUTH=true)\ncurl -s http://localhost:3001/api/payments?limit=1 | python3 -c \"import sys,json; d=json.load(sys.stdin); print('AUTH BYPASS ACTIVE - got', d.get('total','?'), 'records')\" 2>/dev/null || echo \"Error parsing\"\n\n# Test Authentik health\ncurl -s --max-time 3 http://localhost:9100/-/health/ready/ && echo \"Authentik ready\"","depth":26,"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":"AUTH BYPASS ACTIVE - got 235 records\nAuthentik ready","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"payments.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"payments.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Thinking","depth":23,"on_screen":false,"role_description":"disclosure triangle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Thinking","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Good picture. Let me now check the latest MCP SDK version before building.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Check MCP SDK latest version and node version","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"npm view @modelcontextprotocol/sdk version 2>/dev/null && node --version","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":"Exit code 127","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Verify public path configuration","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# Check if the upload endpoints are really public\ngrep -n 'PUBLIC_PATHS\\|upload\\|ingest' /volume2/docker/finance/finance-hub/backend/src/auth.js","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":"<tool_use_error>Cancelled: parallel tool call Bash(npm view @modelcontextprotocol/sdk versi…) errored</tool_use_error>","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Check node version and MCP SDK latest","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"node --version 2>/dev/null && python3 -c \"import urllib.request; import json; d=json.loads(urllib.request.urlopen('https://registry.npmjs.org/@modelcontextprotocol/sdk/latest').read()); print(d['version'])\" 2>/dev/null || echo \"no npm/network\"","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":"v18.20.4\n1.29.0","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":"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":"Fix auth.js: add API key support + remove upload endpoints from PUBLIC_PATHS","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update index.js: add CORS origin restriction via env var","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update .env and .env.example with API_KEY variable","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Build MCP server (stdio, Claude desktop compatible)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Test: restart backend, verify API key auth and MCP connection","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Edit","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"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":"Added 18 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update Todos","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Fix auth.js: add API key support + remove upload endpoints from PUBLIC_PATHS","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update index.js: add CORS origin restriction via env var","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update .env and .env.example with API_KEY variable","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Build MCP server (stdio, Claude desktop compatible)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Test: restart backend, verify API key auth and MCP connection","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Edit","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"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":"Added 3 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update Todos","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Fix auth.js: add API key support + remove upload endpoints from PUBLIC_PATHS","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update index.js: add CORS origin restriction via env var","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update .env and .env.example with API_KEY variable","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Build MCP server (stdio, Claude desktop compatible)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Test: restart backend, verify API key auth and MCP connection","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Generate a secure API key","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"openssl rand -hex 32","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":"94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Edit","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":".env","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":".env","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Added 4 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":".env.example","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":".env.example","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Edit","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":".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":"Added 12 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Also need to pass","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"API_KEY","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"and","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CORS_ORIGIN","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"through docker-compose:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Edit","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"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":"Added 3 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update Todos","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Fix auth.js: add API key support + remove upload endpoints from PUBLIC_PATHS","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update index.js: add CORS origin restriction via env var","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update .env and .env.example with API_KEY variable","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Build MCP server (stdio, Claude desktop compatible)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Test: restart backend, verify API key auth and MCP connection","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Now building the MCP server:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Create MCP directory","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/mcp && ls /volume2/docker/finance/finance-hub/mcp","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(Bash completed with no output)","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"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":"17 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"{\n \"name\": \"finance-hub-mcp\",\n \"version\": \"1.0.0\",\n \"description\": \"MCP server for Finance Hub — exposes transaction tools to Claude\",\n \"main\": \"server.js\",\n \"type\": \"module\",\n \"scripts\": {\n \"start\": \"node server.js\"\n },\n \"dependencies\": {\n \"@modelcontextprotocol/sdk\": \"^1.29.0\"\n },\n \"engines\": {\n \"node\": \">=18\"\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":"server.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"server.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"236 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\n\nconst BASE_URL = (process.env.FINANCE_HUB_URL || 'http://localhost:3001').replace(/\\/$/, '');\nconst API_KEY = process.env.FINANCE_HUB_API_KEY;\n\nif (!API_KEY) {\n process.stderr.write('Warning: FINANCE_HUB_API_KEY not set — requests will fail if DEV_BYPASS_AUTH is off\\n');\n}\n\n// ── HTTP helper ───────────────────────────────────────────────────────────────\n\nasync function api(path, opts = {}) {\n const headers = { 'Content-Type': 'application/json' };\n if (API_KEY) headers['Authorization'] = `Bearer ${API_KEY}`;\n\n const res = await fetch(`${BASE_URL}${path}`, {\n ...opts,\n headers: { ...headers, ...(opts.headers || {}) },\n });\n\n if (res.status === 204) return null;\n const body = await res.text();\n if (!res.ok) throw new Error(`HTTP ${res.status}: ${body}`);\n return body ? JSON.parse(body) : null;\n}\n\n// ── Tool definitions ──────────────────────────────────────────────────────────\n\nconst TOOLS = [\n {\n name: 'list_transactions',\n description:\n 'List finance transactions with optional filters. Returns paginated results including total amount for the filtered set.',\n inputSchema: {\n type: 'object',\n properties: {\n page: { type: 'number', description: 'Page number (default 1)' },\n limit: { type: 'number', description: 'Results per page, max 200 (default 50)' },\n dateFrom: { type: 'string', description: 'Start date YYYY-MM-DD (inclusive)' },\n dateTo: { type: 'string', description: 'End date YYYY-MM-DD (inclusive)' },\n tag: { type: 'string', description: 'Filter by tag name' },\n recipient: { type: 'string', description: 'Substring match on payee name' },\n type: { type: 'string', description: 'Transaction type: POS | ATM | WALLET' },\n source: { type: 'string', description: 'Import source: INGEST | UPLOAD' },\n search: { type: 'string', description: 'Full-text search across rawMessage and recipient' },\n hideBalanceAlerts: { type: 'boolean', description: 'Exclude balance-notification SMS (default false)' },\n sortBy: { type: 'string', description: 'Sort field: date | amount | recipient | createdAt' },\n sortDir: { type: 'string', description: 'asc or desc (default desc)' },\n },\n },\n },\n {\n name: 'spending_by_tag',\n description:\n 'Aggregate spending totals by tag for a date range. Fetches up to 200 transactions and groups them. Good for monthly summaries.',\n inputSchema: {\n type: 'object',\n properties: {\n dateFrom: { type: 'string', description: 'Start date YYYY-MM-DD' },\n dateTo: { type: 'string', description: 'End date YYYY-MM-DD' },\n },\n },\n },\n {\n name: 'get_transaction',\n description: 'Get a single transaction by its numeric ID.',\n inputSchema: {\n type: 'object',\n required: ['id'],\n properties: {\n id: { type: 'number', description: 'Transaction import ID' },\n },\n },\n },\n {\n name: 'list_tags',\n description: 'List all available tags with their colors.',\n inputSchema: { type: 'object', properties: {} },\n },\n {\n name: 'add_tag',\n description: 'Add a tag to a transaction. Creates the tag globally if it does not exist.',\n inputSchema: {\n type: 'object',\n required: ['id', 'name'],\n properties: {\n id: { type: 'number', description: 'Transaction ID' },\n name: { type: 'string', description: 'Tag name (e.g. \"Groceries\")' },\n color: { type: 'string', description: 'Hex color (e.g. \"#22c55e\"). Optional — auto-assigned if omitted.' },\n },\n },\n },\n {\n name: 'remove_tag',\n description: 'Remove a tag from a transaction.',\n inputSchema: {\n type: 'object',\n required: ['id', 'tagId'],\n properties: {\n id: { type: 'number', description: 'Transaction ID' },\n tagId: { type: 'number', description: 'Tag ID (from list_tags or the transaction object)' },\n },\n },\n },\n {\n name: 'health_check',\n description: 'Check Finance Hub backend connectivity and database status.',\n inputSchema: { type: 'object', properties: {} },\n },\n];\n\n// ── Server setup ──────────────────────────────────────────────────────────────\n\nconst server = new Server(\n { name: 'finance-hub', version: '1.0.0' },\n { capabilities: { tools: {} } },\n);\n\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));\n\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args = {} } = request.params;\n\n try {\n switch (name) {\n\n case 'list_transactions': {\n const params = new URLSearchParams();\n for (const [k, v] of Object.entries(args)) {\n if (v !== undefined && v !== null && v !== '') params.set(k, String(v));\n }\n const data = await api(`/api/payments?${params}`);\n return text(JSON.stringify({\n total: data.total,\n page: data.page,\n limit: data.limit,\n totalAmount: data.totalAmount,\n transactions: data.payments,\n }, null, 2));\n }\n\n case 'spending_by_tag': {\n const params = new URLSearchParams({ limit: '200', hideBalanceAlerts: 'true' });\n if (args.dateFrom) params.set('dateFrom', args.dateFrom);\n if (args.dateTo) params.set('dateTo', args.dateTo);\n\n const data = await api(`/api/payments?${params}`);\n\n const byTag = {};\n let untaggedTotal = 0, untaggedCount = 0;\n\n for (const tx of data.payments) {\n const amount = tx.amount ?? 0;\n if (!tx.tags?.length) {\n untaggedTotal += amount;\n untaggedCount++;\n } else {\n for (const tag of tx.tags) {\n if (!byTag[tag.name]) byTag[tag.name] = { total: 0, count: 0 };\n byTag[tag.name].total += amount;\n byTag[tag.name].count++;\n }\n }\n }\n\n const breakdown = Object.entries(byTag)\n .map(([tag, s]) => ({ tag, total: round2(s.total), count: s.count }))\n .sort((a, b) => b.total - a.total);\n\n if (untaggedCount) breakdown.push({ tag: '(untagged)', total: round2(untaggedTotal), count: untaggedCount });\n\n return text(JSON.stringify({\n period: { from: args.dateFrom ?? null, to: args.dateTo ?? null },\n totalTransactions: data.total,\n note: data.total > 200 ? `Only first 200 of ${data.total} transactions included — refine the date range for full accuracy` : undefined,\n breakdown,\n }, null, 2));\n }\n\n case 'get_transaction': {\n const data = await api(`/api/payments/${args.id}`);\n return text(JSON.stringify(data, null, 2));\n }\n\n case 'list_tags': {\n const data = await api('/api/payments/meta/tags');\n return text(JSON.stringify(data, null, 2));\n }\n\n case 'add_tag': {\n const data = await api(`/api/payments/${args.id}/tags`, {\n method: 'POST',\n body: JSON.stringify({ name: args.name, color: args.color }),\n });\n return text(JSON.stringify(data, null, 2));\n }\n\n case 'remove_tag': {\n await api(`/api/payments/${args.id}/tags/${args.tagId}`, { method: 'DELETE' });\n return text('Tag removed successfully');\n }\n\n case 'health_check': {\n const data = await api('/api/health');\n return text(JSON.stringify(data, null, 2));\n }\n\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n } catch (err) {\n return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };\n }\n});\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction text(str) {\n return { content: [{ type: 'text', text: str }] };\n}\n\nfunction round2(n) {\n return Math.round(n * 100) / 100;\n}\n\n// ── Entry point ───────────────────────────────────────────────────────────────\n\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\nprocess.stderr.write(`Finance Hub MCP server connected to ${BASE_URL}\\n`);","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Now install the MCP SDK and test it:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Install MCP SDK dependencies","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"cd /volume2/docker/finance/finance-hub/mcp && node --version && npm install --save-exact 2>&1 | tail -5","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":"v18.20.4\n/bin/bash: line 1: npm: command not found","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Locate npm","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"which npm || find /usr -name npm 2>/dev/null | head -5 || find /usr/local -name npm 2>/dev/null | head -5 || ls /root/.nvm/versions/node/ 2>/dev/null","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(Bash completed with no output)","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Check system info","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ls /proc/1/exe 2>/dev/null && cat /proc/version && uname -a","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":"Exit code 2","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Find npm via Docker","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"find /volume2 /opt /home -name npm -type f 2>/dev/null | head -5\ndocker run --rm node:18-alpine node --version 2>/dev/null | head -1","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":"/home/Adm1n/.nvm/versions/node/v24.14.1/lib/node_modules/corepack/shims/npm\n/home/Adm1n/.nvm/versions/node/v24.14.1/lib/node_modules/npm/bin/npm\n/home/Adm1n/.nvm/versions/node/v24.14.1/lib/node_modules/corepack/shims/nodewin/npm","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Install MCP SDK via located npm","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/home/Adm1n/.nvm/versions/node/v24.14.1/lib/node_modules/npm/bin/npm-cli.js install --save-exact 2>&1 | tail -5","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":"28 packages are looking for funding\n run `npm fund` for details\n\nfound 0 vulnerabilities","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Verify MCP package installed","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ls && cat package.json | python3 -c \"import json,sys; d=json.load(sys.stdin); print(d['dependencies'])\"","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":"node_modules\npackage.json\npackage-lock.json\nserver.js\n{'@modelcontextprotocol/sdk': '^1.29.0'}","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. Now let me test the MCP server can at least start and call the health check:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Smoke test MCP server startup","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FINANCE_HUB_URL=http://localhost:3001 FINANCE_HUB_API_KEY=94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c \\\n echo '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\",\"params\":{}}' | timeout 5 node server.js 2>/dev/null | head -3 || echo \"NODE test (expected timeout on stdin wait)\"","depth":26,"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":"{\"result\":{\"tools\":[{\"name\":\"list_transactions\",\"description\":\"List finance transactions with optional filters. Returns paginated results including total amount for the filtered set.\",\"inputSchema\":{\"type\":\"object\",\"properties\":{\"page\":{\"type\":\"number\",\"description\":\"Page number (default 1)\"},\"limit\":{\"type\":\"number\",\"description\":\"Results per page, max 200 (default 50)\"},\"dateFrom\":{\"type\":\"string\",\"description\":\"Start date YYYY-MM-DD (inclusive)\"},\"dateTo\":{\"type\":\"string\",\"description\":\"End date YYYY-MM-DD (inclusive)\"},\"tag\":{\"type\":\"string\",\"description\":\"Filter by tag name\"},\"recipient\":{\"type\":\"string\",\"description\":\"Substring match on payee name\"},\"type\":{\"type\":\"string\",\"description\":\"Transaction type: POS | ATM | WALLET\"},\"source\":{\"type\":\"string\",\"description\":\"Import source: INGEST | UPLOAD\"},\"search\":{\"type\":\"string\",\"description\":\"Full-text search across rawMessage and recipient\"},\"hideBalanceAlerts\":{\"type\":\"boolean\",\"description\":\"Exclude balance-notification SMS (default false)\"},\"sortBy\":{\"type\":\"string\",\"description\":\"Sort field: date | amount | recipient | createdAt\"},\"sortDir\":{\"type\":\"string\",\"description\":\"asc or desc (default desc)\"}}}},{\"name\":\"spending_by_tag\",\"description\":\"Aggregate spending totals by tag for a date range. Fetches up to 200 transactions and groups them. Good for monthly summaries.\",\"inputSchema\":{\"type\":\"object\",\"properties\":{\"dateFrom\":{\"type\":\"string\",\"description\":\"Start date YYYY-MM-DD\"},\"dateTo\":{\"type\":\"string\",\"description\":\"End date YYYY-MM-DD\"}}}},{\"name\":\"get_transaction\",\"description\":\"Get a single transaction by its numeric ID.\",\"inputSchema\":{\"type\":\"object\",\"required\":[\"id\"],\"properties\":{\"id\":{\"type\":\"number\",\"description\":\"Transaction import ID\"}}}},{\"name\":\"list_tags\",\"description\":\"List all available tags with their colors.\",\"inputSchema\":{\"type\":\"object\",\"properties\":{}}},{\"name\":\"add_tag\",\"description\":\"Add a tag to a transaction. Creates the tag globally if it does not exist.\",\"inputSchema\":{\"type\":\"object\",\"required\":[\"id\",\"name\"],\"properties\":{\"id\":{\"type\":\"number\",\"description\":\"Transaction ID\"},\"name\":{\"type\":\"string\",\"description\":\"Tag name (e.g. \\\"Groceries\\\")\"},\"color\":{\"type\":\"string\",\"description\":\"Hex color (e.g. \\\"#22c55e\\\"). Optional — auto-assigned if omitted.\"}}}},{\"name\":\"remove_tag\",\"description\":\"Remove a tag from a transaction.\",\"inputSchema\":{\"type\":\"object\",\"required\":[\"id\",\"tagId\"],\"properties\":{\"id\":{\"type\":\"number\",\"description\":\"Transaction ID\"},\"tagId\":{\"type\":\"number\",\"description\":\"Tag ID (from list_tags or the transaction object)\"}}}},{\"name\":\"health_check\",\"description\":\"Check Finance Hub backend connectivity and database status.\",\"inputSchema\":{\"type\":\"object\",\"properties\":{}}}]},\"jsonrpc\":\"2.0\",\"id\":1}","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":"MCP server responds correctly. Now test an actual tool call:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Test MCP health_check tool against live backend","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\\\n printf '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\",\"params\":{}}\\n{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/call\",\"params\":{\"name\":\"health_check\",\"arguments\":{}}}\\n' | \\\n FINANCE_HUB_URL=http://localhost:3001 FINANCE_HUB_API_KEY=94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c \\\n timeout 5 node server.js 2>/dev/null | tail -1 | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d['result']['content'][0]['text'])\"","depth":26,"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":"{\n \"status\": \"ok\",\n \"timestamp\": \"2026-05-09T16:19:09.977Z\",\n \"storage\": {\n \"type\": \"PostgreSQL\",\n \"host\": \"db\",\n \"database\": \"finance_hub\"\n }\n}","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Rebuild backend with API key auth changes","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# Test the API key auth directly against the backend (backend still has DEV_BYPASS_AUTH=true, need to restart first)\n# First rebuild with the new code\ncd /volume2/docker/finance/finance-hub && docker compose up -d --build backend 2>&1 | tail -8","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":"time=\"2026-05-09T19:19:13+03:00\" level=warning msg=\"/volume2/docker/finance/finance-hub/docker-compose.yml: `version` is obsolete\"\npermission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get \"http://%2Fvar%2Frun%2Fdocker.sock/v1.45/containers/json?all=1&filters=%7B%22label%22%3A%7B%22com.docker.compose.config-hash%22%3Atrue%2C%22com.docker.compose.project%3Dfinance-hub%22%3Atrue%7D%7D\": dial unix /var/run/docker.sock: connect: permission denied","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Rebuild backend with sudo","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"sudo docker compose -f /volume2/docker/finance/finance-hub/docker-compose.yml up -d --build backend 2>&1 | tail -10","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":"sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper\nsudo: a password is required","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":"Docker needs sudo+password. Let me verify the auth changes are correct by testing the logic directly:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Unit test the auth middleware logic","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"node - << 'EOF'\n// Simulate the auth middleware logic\nconst API_KEY = '94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c';\nprocess.env.API_KEY = API_KEY;\n\nconst { authentikMiddleware } = require('/volume2/docker/finance/finance-hub/backend/src/auth.js');\n\nfunction testReq(path, headers = {}) {\n const res = { status(code) { this.code = code; return this; }, json(body) { return body; } };\n const req = { path, headers };\n let passed = false;\n authentikMiddleware(req, res, () => { passed = true; });\n return { passed, code: res.code, user: req.user };\n}\n\n// Public path — no auth needed\nlet r = testReq('/api/health', {});\nconsole.assert(r.passed, 'health should be public');\nconsole.log('✓ /api/health is public');\n\n// Valid API key\nr = testReq('/api/payments', { authorization: `Bearer ${API_KEY}` });\nconsole.assert(r.passed, 'valid key should pass');\nconsole.assert(r.user.username === 'api-key', 'api user');\nconsole.log('✓ valid API key passes');\n\n// Wrong API key\nr = testReq('/api/payments', { authorization: 'Bearer wrongkey' });\nconsole.assert(!r.passed, 'wrong key should fail');\nconsole.assert(r.code === 401, '401 on bad key');\nconsole.log('✓ wrong API key returns 401');\n\n// No auth + no bypass + no authentik header\nprocess.env.DEV_BYPASS_AUTH = 'false';\nr = testReq('/api/payments', {});\nconsole.assert(!r.passed && r.code === 401, 'no creds → 401');\nconsole.log('✓ no credentials returns 401');\n\n// Upload endpoints no longer public\nr = testReq('/api/upload/csv', {});\nconsole.assert(!r.passed && r.code === 401, 'upload/csv requires auth');\nconsole.log('✓ /api/upload/csv now requires auth (was public, now fixed)');\n\n// Authentik header pass-through\nr = testReq('/api/payments', { 'x-authentik-username': 'lukastest', 'x-authentik-email': 'test@test.com' });\nconsole.assert(r.passed && r.user.username === 'lukastest', 'authentik header works');\nconsole.log('✓ Authentik X-authentik-username header works');\n\nconsole.log('\\nAll auth tests passed.');\nEOF","depth":26,"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":"✓ /api/health is public\n✓ valid API key passes\n✓ wrong API key returns 401\n✓ no credentials returns 401\n✓ /api/upload/csv now requires auth (was public, now fixed)\n✓ Authentik X-authentik-username header works\n\nAll auth tests passed.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"All auth cases pass. Now test the MCP spending_by_tag tool against the live backend (with DEV_BYPASS_AUTH still on):","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Test spending_by_tag MCP tool against live backend","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"cd /volume2/docker/finance/finance-hub/mcp && \\\n printf '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\",\"params\":{}}\\n{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/call\",\"params\":{\"name\":\"spending_by_tag\",\"arguments\":{\"dateFrom\":\"2026-05-01\",\"dateTo\":\"2026-05-09\"}}}\\n' | \\\n FINANCE_HUB_URL=http://localhost:3001 FINANCE_HUB_API_KEY=94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c \\\n timeout 8 node server.js 2>/dev/null | grep '\"id\":2' | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d['result']['content'][0]['text'][:500])\"","depth":26,"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":"{\n \"period\": {\n \"from\": \"2026-05-01\",\n \"to\": \"2026-05-09\"\n },\n \"totalTransactions\": 36,\n \"breakdown\": [\n {\n \"tag\": \"Bills\",\n \"total\": 117.9,\n \"count\": 6\n },\n {\n \"tag\": \"(untagged)\",\n \"total\": 1153.87,\n \"count\": 22\n }\n ]\n}","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MCP tools work correctly against real data. Let me write the Claude desktop config example and the","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".gitignore","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"for the mcp dir:","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":"claude_desktop_config.example.json","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"claude_desktop_config.example.json","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"14 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"{\n \"_comment\": \"Add this block to ~/.config/claude/claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json)\",\n \"mcpServers\": {\n \"finance-hub\": {\n \"command\": \"node\",\n \"args\": [\"/volume2/docker/finance/finance-hub/mcp/server.js\"],\n \"env\": {\n \"FINANCE_HUB_URL\": \"http://localhost:3001\",\n \"FINANCE_HUB_API_KEY\": \"94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c\"\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":".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":"2 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"node_modules/","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update Todos","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Fix auth.js: add API key support + remove upload endpoints from PUBLIC_PATHS","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update index.js: add CORS origin restriction via env var","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update .env and .env.example with API_KEY variable","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Build MCP server (stdio, Claude desktop compatible)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Test: restart backend, verify API key auth and MCP connection","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Now let me save relevant project context to memory:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"MEMORY.md","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"MEMORY.md","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":"MEMORY.md","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"MEMORY.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"4 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# Memory Index\n\n- [project_finance_hub.md](project_finance_hub.md) — Finance Hub architecture, auth design, MCP server, API key setup","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":"project_finance_hub.md","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"project_finance_hub.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"35 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"---\nname: Finance Hub project state\ndescription: Architecture, auth design, API key, MCP server location and tools for the finance-hub project\ntype: project\n---\n\nFinance Hub is a personal finance tracker at `/volume2/docker/finance/finance-hub/`.\n\n**Running services** (as of 2026-05-09):\n- Backend: port 3001 (Express/Prisma, PostgreSQL)\n- Frontend: port 5175 (React/Vite)\n- Adminer: port 8092\n- Authentik: port 9100 (auth.lakylak.xyz, tag 2026.2.1)\n\n**Auth design:**\n- Production: NPM (Nginx Proxy Manager) + Authentik forward-auth outpost → injects `X-authentik-username` header\n- `DEV_BYPASS_AUTH=true` is currently set in `.env` — app runs without real auth\n- API key auth added: `Authorization: Bearer <API_KEY>` bypasses Authentik header check (used by MCP/scripts)\n- API_KEY in `.env`: `94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c`\n\n**Public endpoints** (no auth): `/api/health`, `/api/payments/ingest`\n\n**Security fix applied (2026-05-09):** Removed `/api/upload/csv` and `/api/upload/preview` from PUBLIC_PATHS — they were incorrectly public.\n\n**MCP server:** `/volume2/docker/finance/finance-hub/mcp/server.js`\n- Stdio transport, works with Claude desktop\n- Tools: list_transactions, spending_by_tag, get_transaction, list_tags, add_tag, remove_tag, health_check\n- Env: FINANCE_HUB_URL, FINANCE_HUB_API_KEY\n- Config example: `mcp/claude_desktop_config.example.json`\n\n**To enable real Authentik auth:** Set `DEV_BYPASS_AUTH=false` in `.env`, configure NPM proxy host for finance-hub with the Authentik NPM nginx snippet (see `/volume2/docker/finance/auth/README.md`).\n\n**Why:** Application had no production auth despite Authentik being available and running.\n**How to apply:** When asked about enabling auth or going to production, walk through NPM proxy + Authentik outpost steps from the README. API_KEY is already set for MCP.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Here's a full summary of what was done and the findings:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"What was built and fixed","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"What was built and fixed","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Security fixes","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Security fixes","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bug fixed:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/api/upload/csv","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"and","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/api/upload/preview","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"were in","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PUBLIC_PATHS","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— anyone on the network could upload files without authentication. Both are now protected. Only","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/api/health","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"and","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/api/payments/ingest","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"remain public.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CORS restriction added:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"index.js","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"now reads","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CORS_ORIGIN","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"from env. Set it to your frontend domain (e.g.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"https://finance.lakylak.xyz","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":") in","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".env","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"for production.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"API key auth layer (backend/src/auth.js)","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"API key auth layer (","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"backend/src/auth.js","depth":23,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"backend/src/auth.js","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":")","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Requests with","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Authorization: Bearer <key>","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"are now validated before the Authentik header check. Set","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"API_KEY=","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"in","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".env","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(already has a generated key). Wrong key →","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"401","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"immediately (no fallthrough). This is what the MCP server and scripts use.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"MCP server (mcp/server.js)","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"MCP server (","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"mcp/server.js","depth":23,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"mcp/server.js","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":")","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Stdio transport, works with Claude desktop. Tested live against the running backend. Tools:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Tool","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"What it does","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"list_transactions","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Paginated list with all filters","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"spending_by_tag","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Aggregates spending by tag for a period","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"get_transaction","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Single record by ID","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"list_tags","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"All tags","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"add_tag","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"remove_tag","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Tag management","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"health_check","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Backend connectivity check","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Tool","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"list_transactions","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"spending_by_tag","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"get_transaction","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"list_tags","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"add_tag","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"remove_tag","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"health_check","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"What it does","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Paginated list with all filters","depth":25,"on_screen":false,"role_description":"text"}]...
|
1236327308389593145
|
-6500787940164139005
|
click
|
accessibility
|
NULL
|
Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧ Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧G) - 10 pending changes
10
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
mcp
scripts
.env
.env.example
M
.gitignore
M
docker-compose.yml
M
README.md
sms_export.json
payments-logger
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
docker-compose.yml, Editor Group 1
.env, Editor Group 1
.env.example, preview, Editor Group 1
report(1).csv, Editor Group 1
report(2).csv, Editor Group 1
sms_export.json, Editor Group 1
# ── Database ───────────────────────────────────────────────────────────────────
[ENV_SECRET]
# ── Notifier service ──────────────────────────────────────────────────────────
NOTIFIER_URL=[URL_WITH_CREDENTIALS]
# Secret key — generate with: openssl rand -base64 36
[ENV_SECRET]
# Public URL authentik is reachable at (used for redirects and the outpost)
AUTHENTIK_HOST=[URL_WITH_CREDENTIALS] version 2>/dev/null && node --version
Copy code to clipboard
OUT
Exit code 127
Bash
Verify public path configuration
IN
# Check if the upload endpoints are really public
grep -n 'PUBLIC_PATHS\|upload\|ingest' /volume2/docker/finance/finance-hub/backend/src/auth.js
Copy code to clipboard
OUT
<tool_use_error>Cancelled: parallel tool call Bash(npm view @modelcontextprotocol/sdk versi…) errored</tool_use_error>
Bash
Check node version and MCP SDK latest
IN
node --version 2>/dev/null && python3 -c "import urllib.request; import json; d=json.loads(urllib.request.urlopen('[URL_WITH_CREDENTIALS] "^1.29.0"
},
"engines": {
"node": ">=18"
}
}
Write
server.js
server.js
236 lines
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
const BASE_URL = (process.env.FINANCE_HUB_URL || '[URL_WITH_CREDENTIALS] '^1.29.0'}
Thinking
Thinking
Good. Now let me test the MCP server can at least start and call the health check:
Bash
Smoke test MCP server startup
IN
FINANCE_HUB_URL=http://localhost:3001 [ENV_SECRET] \
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | timeout 5 node server.js 2>/dev/null | head -3 || echo "NODE test (expected timeout on stdin wait)"
Copy code to clipboard
OUT
{"result":{"tools":[{"name":"list_transactions","description":"List finance transactions with optional filters. Returns paginated results including total amount for the filtered set.","inputSchema":{"type":"object","properties":{"page":{"type":"number","description":"Page number (default 1)"},"limit":{"type":"number","description":"Results per page, max 200 (default 50)"},"dateFrom":{"type":"string","description":"Start date YYYY-MM-DD (inclusive)"},"dateTo":{"type":"string","description":"End date YYYY-MM-DD (inclusive)"},"tag":{"type":"string","description":"Filter by tag name"},"recipient":{"type":"string","description":"Substring match on payee name"},"type":{"type":"string","description":"Transaction type: POS | ATM | WALLET"},"source":{"type":"string","description":"Import source: INGEST | UPLOAD"},"search":{"type":"string","description":"Full-text search across rawMessage and recipient"},"hideBalanceAlerts":{"type":"boolean","description":"Exclude balance-notification SMS (default false)"},"sortBy":{"type":"string","description":"Sort field: date | amount | recipient | createdAt"},"sortDir":{"type":"string","description":"asc or desc (default desc)"}}}},{"name":"spending_by_tag","description":"Aggregate spending totals by tag for a date range. Fetches up to 200 transactions and groups them. Good for monthly summaries.","inputSchema":{"type":"object","properties":{"dateFrom":{"type":"string","description":"Start date YYYY-MM-DD"},"dateTo":{"type":"string","description":"End date YYYY-MM-DD"}}}},{"name":"get_transaction","description":"Get a single transaction by its numeric ID.","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"number","description":"Transaction import ID"}}}},{"name":"list_tags","description":"List all available tags with their colors.","inputSchema":{"type":"object","properties":{}}},{"name":"add_tag","description":"Add a tag to a transaction. Creates the tag globally if it does not exist.","inputSchema":{"type":"object","required":["id","name"],"properties":{"id":{"type":"number","description":"Transaction ID"},"name":{"type":"string","description":"Tag name (e.g. \"Groceries\")"},"color":{"type":"string","description":"Hex color (e.g. \"#22c55e\"). Optional — auto-assigned if omitted."}}}},{"name":"remove_tag","description":"Remove a tag from a transaction.","inputSchema":{"type":"object","required":["id","tagId"],"properties":{"id":{"type":"number","description":"Transaction ID"},"tagId":{"type":"number","description":"Tag ID (from list_tags or the transaction object)"}}}},{"name":"health_check","description":"Check Finance Hub backend connectivity and database status.","inputSchema":{"type":"object","properties":{}}}]},"jsonrpc":"2.0","id":1}
Thinking
Thinking
MCP server responds correctly. Now test an actual tool call:
Bash
Test MCP health_check tool against live backend
IN
\
printf '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}\n{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"health_check","arguments":{}}}\n' | \
FINANCE_HUB_URL=http://localhost:3001 [ENV_SECRET] \
timeout 5 node server.js 2>/dev/null | tail -1 | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['result']['content'][0]['text'])"
Copy code to clipboard
OUT
{
"status": "ok",
"timestamp": "2026-05-09T16:19:09.977Z",
"storage": {
"type": "PostgreSQL",
"host": "db",
"database": "finance_hub"
}
}
Bash
Rebuild backend with API key auth changes
IN
# Test the API key auth directly against the backend (backend still has DEV_BYPASS_AUTH=true, need to restart first)
# First rebuild with the new code
cd /volume2/docker/finance/finance-hub && docker compose up -d --build backend 2>&1 | tail -8
Copy code to clipboard
OUT
time="2026-05-09T19:19:13+03:00" level=warning msg="/volume2/docker/finance/finance-hub/docker-compose.yml: `version` is obsolete"
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.45/containers/json?all=1&filters=%7B%22label%22%3A%7B%22com.docker.compose.config-hash%22%3Atrue%2C%22com.docker.compose.project%3Dfinance-hub%22%3Atrue%7D%7D": dial unix /var/run/docker.sock: connect: permission denied
Bash
Rebuild backend with sudo
IN
sudo docker compose -f /volume2/docker/finance/finance-hub/docker-compose.yml up -d --build backend 2>&1 | tail -10
Copy code to clipboard
OUT
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
sudo: a password is required
Thinking
Thinking
Docker needs sudo+password. Let me verify the auth changes are correct by testing the logic directly:
Bash
Unit test the auth middleware logic
IN
node - << 'EOF'
// Simulate the auth middleware logic
const [ENV_SECRET];
process.env.API_KEY = API_KEY;
const { authentikMiddleware } = require('/volume2/docker/finance/finance-hub/backend/src/auth.js');
function testReq(path, headers = {}) {
const res = { status(code) { this.code = code; return this; }, json(body) { return body; } };
const req = { path, headers };
let passed = false;
authentikMiddleware(req, res, () => { passed = true; });
return { passed, code: res.code, user: req.user };
}
// Public path — no auth needed
let r = testReq('/api/health', {});
console.assert(r.passed, 'health should be public');
console.log('✓ /api/health is public');
// Valid API key
r = testReq('/api/payments', { authorization: `Bearer ${API_KEY}` });
console.assert(r.passed, 'valid key should pass');
console.assert(r.user.username === 'api-key', 'api user');
console.log('✓ valid API key passes');
// Wrong API key
r = testReq('/api/payments', { authorization: 'Bearer wrongkey' });
console.assert(!r.passed, 'wrong key should fail');
console.assert(r.code === 401, '401 on bad key');
console.log('✓ wrong API key returns 401');
// No auth + no bypass + no authentik header
process.env.DEV_BYPASS_AUTH = 'false';
r = testReq('/api/payments', {});
console.assert(!r.passed && r.code === 401, 'no creds → 401');
console.log('✓ no credentials returns 401');
// Upload endpoints no longer public
r = testReq('/api/upload/csv', {});
console.assert(!r.passed && r.code === 401, 'upload/csv requires auth');
console.log('✓ /api/upload/csv now requires auth (was public, now fixed)');
// Authentik header pass-through
r = testReq('/api/payments', { 'x-authentik-username': 'lukastest', 'x-authentik-email': '[EMAIL]' });
console.assert(r.passed && r.user.username === 'lukastest', 'authentik header works');
console.log('✓ Authentik X-authentik-username header works');
console.log('\nAll auth tests passed.');
EOF
Copy code to clipboard
OUT
✓ /api/health is public
✓ valid API key passes
✓ wrong API key returns 401
✓ no credentials returns 401
✓ /api/upload/csv now requires auth (was public, now fixed)
✓ Authentik X-authentik-username header works
All auth tests passed.
All auth cases pass. Now test the MCP spending_by_tag tool against the live backend (with DEV_BYPASS_AUTH still on):
Bash
Test spending_by_tag MCP tool against live backend
IN
cd /volume2/docker/finance/finance-hub/mcp && \
printf '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}\n{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"spending_by_tag","arguments":{"dateFrom":"2026-05-01","dateTo":"2026-05-09"}}}\n' | \
FINANCE_HUB_URL=http://localhost:3001 [ENV_SECRET] \
timeout 8 node server.js 2>/dev/null | grep '"id":2' | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['result']['content'][0]['text'][:500])"
Copy code to clipboard
OUT
{
"period": {
"from": "2026-05-01",
"to": "2026-05-09"
},
"totalTransactions": 36,
"breakdown": [
{
"tag": "Bills",
"total": 117.9,
"count": 6
},
{
"tag": "(untagged)",
"total": 1153.87,
"count": 22
}
]
}
MCP tools work correctly against real data. Let me write the Claude desktop config example and the
.gitignore
for the mcp dir:
Write
claude_desktop_config.example.json
claude_desktop_config.example.json
14 lines
{
"_comment": "Add this block to ~/.config/claude/claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json)",
"mcpServers": {
"finance-hub": {
"command": "node",
"args": ["/volume2/docker/finance/finance-hub/mcp/server.js"],
"env": {
"FINANCE_HUB_URL": "http://localhost:3001",
"FINANCE_HUB_API_KEY": "94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c"
}
}
}
}
Write
.gitignore
.gitignore
2 lines
node_modules/
Update Todos
Fix auth.js: add API key support + remove upload endpoints from PUBLIC_PATHS
Update index.js: add CORS origin restriction via env var
Update .env and .env.example with API_KEY variable
Build MCP server (stdio, Claude desktop compatible)
Test: restart backend, verify API key auth and MCP connection
Now let me save relevant project context to memory:
Read
MEMORY.md
MEMORY.md
Write
MEMORY.md
MEMORY.md
4 lines
# Memory Index
- [project_finance_hub.md](project_finance_hub.md) — Finance Hub architecture, auth design, MCP server, API key setup
Write
project_finance_hub.md
project_finance_hub.md
35 lines
---
name: Finance Hub project state
description: Architecture, auth design, API key, MCP server location and tools for the finance-hub project
type: project
---
Finance Hub is a personal finance tracker at `/volume2/docker/finance/finance-hub/`.
**Running services** (as of 2026-05-09):
- Backend: port 3001 (Express/Prisma, PostgreSQL)
- Frontend: port 5175 (React/Vite)
- Adminer: port 8092
- Authentik: port 9100 (auth.lakylak.xyz, tag 2026.2.1)
**Auth design:**
- Production: NPM (Nginx Proxy Manager) + Authentik forward-auth outpost → injects `X-authentik-username` header
- `DEV_BYPASS_AUTH=true` is currently set in `.env` — app runs without real auth
- API key auth added: `Authorization: Bearer <API_KEY>` bypasses Authentik header check (used by MCP/scripts)
- API_KEY in `.env`: `94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c`
**Public endpoints** (no auth): `/api/health`, `/api/payments/ingest`
**Security fix applied (2026-05-09):** Removed `/api/upload/csv` and `/api/upload/preview` from PUBLIC_PATHS — they were incorrectly public.
**MCP server:** `/volume2/docker/finance/finance-hub/mcp/server.js`
- Stdio transport, works with Claude desktop
- Tools: list_transactions, spending_by_tag, get_transaction, list_tags, add_tag, remove_tag, health_check
- Env: FINANCE_HUB_URL, FINANCE_HUB_API_KEY
- Config example: `mcp/claude_desktop_config.example.json`
**To enable real Authentik auth:** Set `DEV_BYPASS_AUTH=false` in `.env`, configure NPM proxy host for finance-hub w...
|
13891
|
NULL
|
NULL
|
NULL
|
|
14182
|
630
|
40
|
2026-05-09T17:03:28.596483+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778346208596_m2.jpg...
|
Code
|
Implement Authentik inte… — finance [SSH: nas]
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧ Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧G) - 12 pending changes
12
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
mcp
scripts
.env
.env.example
M
.gitignore
M
docker-compose.yml
M
README.md
sms_export.json
payments-logger
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
docker-compose.yml, Editor Group 1
.env, Editor Group 1
.env.example, preview, Editor Group 1
report(1).csv, Editor Group 1
report(2).csv, Editor Group 1
sms_export.json, Editor Group 1
# ── Database ───────────────────────────────────────────────────────────────────
[ENV_SECRET]
# ── Notifier service ──────────────────────────────────────────────────────────
NOTIFIER_URL=[URL_WITH_CREDENTIALS]
# Secret key — generate with: openssl rand -base64 36
[ENV_SECRET]
# Public URL authentik is reachable at (used for redirects and the outpost)
AUTHENTIK_HOST=[URL_WITH_CREDENTIALS] version 2>/dev/null && node --version
Copy code to clipboard
OUT
Exit code 127
Bash
Verify public path configuration
IN
# Check if the upload endpoints are really public
grep -n 'PUBLIC_PATHS\|upload\|ingest' /volume2/docker/finance/finance-hub/backend/src/auth.js
Copy code to clipboard
OUT
<tool_use_error>Cancelled: parallel tool call Bash(npm view @modelcontextprotocol/sdk versi…) errored</tool_use_error>
Bash
Check node version and MCP SDK latest
IN
node --version 2>/dev/null && python3 -c "import urllib.request; import json; d=json.loads(urllib.request.urlopen('[URL_WITH_CREDENTIALS] "^1.29.0"
},
"engines": {
"node": ">=18"
}
}
Write
server.js
server.js
236 lines
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
const BASE_URL = (process.env.FINANCE_HUB_URL || '[URL_WITH_CREDENTIALS] '^1.29.0'}
Thinking
Thinking
Good. Now let me test the MCP server can at least start and call the health check:
Bash
Smoke test MCP server startup
IN
FINANCE_HUB_URL=http://localhost:3001 [ENV_SECRET] \
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | timeout 5 node server.js 2>/dev/null | head -3 || echo "NODE test (expected timeout on stdin wait)"
Copy code to clipboard
OUT
{"result":{"tools":[{"name":"list_transactions","description":"List finance transactions with optional filters. Returns paginated results including total amount for the filtered set.","inputSchema":{"type":"object","properties":{"page":{"type":"number","description":"Page number (default 1)"},"limit":{"type":"number","description":"Results per page, max 200 (default 50)"},"dateFrom":{"type":"string","description":"Start date YYYY-MM-DD (inclusive)"},"dateTo":{"type":"string","description":"End date YYYY-MM-DD (inclusive)"},"tag":{"type":"string","description":"Filter by tag name"},"recipient":{"type":"string","description":"Substring match on payee name"},"type":{"type":"string","description":"Transaction type: POS | ATM | WALLET"},"source":{"type":"string","description":"Import source: INGEST | UPLOAD"},"search":{"type":"string","description":"Full-text search across rawMessage and recipient"},"hideBalanceAlerts":{"type":"boolean","description":"Exclude balance-notification SMS (default false)"},"sortBy":{"type":"string","description":"Sort field: date | amount | recipient | createdAt"},"sortDir":{"type":"string","description":"asc or desc (default desc)"}}}},{"name":"spending_by_tag","description":"Aggregate spending totals by tag for a date range. Fetches up to 200 transactions and groups them. Good for monthly summaries.","inputSchema":{"type":"object","properties":{"dateFrom":{"type":"string","description":"Start date YYYY-MM-DD"},"dateTo":{"type":"string","description":"End date YYYY-MM-DD"}}}},{"name":"get_transaction","description":"Get a single transaction by its numeric ID.","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"number","description":"Transaction import ID"}}}},{"name":"list_tags","description":"List all available tags with their colors.","inputSchema":{"type":"object","properties":{}}},{"name":"add_tag","description":"Add a tag to a transaction. Creates the tag globally if it does not exist.","inputSchema":{"type":"object","required":["id","name"],"properties":{"id":{"type":"number","description":"Transaction ID"},"name":{"type":"string","description":"Tag name (e.g. \"Groceries\")"},"color":{"type":"string","description":"Hex color (e.g. \"#22c55e\"). Optional — auto-assigned if omitted."}}}},{"name":"remove_tag","description":"Remove a tag from a transaction.","inputSchema":{"type":"object","required":["id","tagId"],"properties":{"id":{"type":"number","description":"Transaction ID"},"tagId":{"type":"number","description":"Tag ID (from list_tags or the transaction object)"}}}},{"name":"health_check","description":"Check Finance Hub backend connectivity and database status.","inputSchema":{"type":"object","properties":{}}}]},"jsonrpc":"2.0","id":1}
Thinking
Thinking
MCP server responds correctly. Now test an actual tool call:
Bash
Test MCP health_check tool against live backend
IN
\
printf '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}\n{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"health_check","arguments":{}}}\n' | \
FINANCE_HUB_URL=http://localhost:3001 [ENV_SECRET] \
timeout 5 node server.js 2>/dev/null | tail -1 | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['result']['content'][0]['text'])"
Copy code to clipboard
OUT
{
"status": "ok",
"timestamp": "2026-05-09T16:19:09.977Z",
"storage": {
"type": "PostgreSQL",
"host": "db",
"database": "finance_hub"
}
}
Bash
Rebuild backend with API key auth changes
IN
# Test the API key auth directly against the backend (backend still has DEV_BYPASS_AUTH=true, need to restart first)
# First rebuild with the new code
cd /volume2/docker/finance/finance-hub && docker compose up -d --build backend 2>&1 | tail -8
Copy code to clipboard
OUT
time="2026-05-09T19:19:13+03:00" level=warning msg="/volume2/docker/finance/finance-hub/docker-compose.yml: `version` is obsolete"
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.45/containers/json?all=1&filters=%7B%22label%22%3A%7B%22com.docker.compose.config-hash%22%3Atrue%2C%22com.docker.compose.project%3Dfinance-hub%22%3Atrue%7D%7D": dial unix /var/run/docker.sock: connect: permission denied
Bash
Rebuild backend with sudo
IN
sudo docker compose -f /volume2/docker/finance/finance-hub/docker-compose.yml up -d --build backend 2>&1 | tail -10
Copy code to clipboard
OUT
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
sudo: a password is required
Thinking
Thinking
Docker needs sudo+password. Let me verify the auth changes are correct by testing the logic directly:
Bash
Unit test the auth middleware logic
IN
node - << 'EOF'
// Simulate the auth middleware logic
const [ENV_SECRET];
process.env.API_KEY = API_KEY;
const { authentikMiddleware } = require('/volume2/docker/finance/finance-hub/backend/src/auth.js');
function testReq(path, headers = {}) {
const res = { status(code) { this.code = code; return this; }, json(body) { return body; } };
const req = { path, headers };
let passed = false;
authentikMiddleware(req, res, () => { passed = true; });
return { passed, code: res.code, user: req.user };
}
// Public path — no auth needed
let r = testReq('/api/health', {});
console.assert(r.passed, 'health should be public');
console.log('✓ /api/health is public');
// Valid API key
r = testReq('/api/payments', { authorization: `Bearer ${API_KEY}` });
console.assert(r.passed, 'valid key should pass');
console.assert(r.user.username === 'api-key', 'api user');
console.log('✓ valid API key passes');
// Wrong API key
r = testReq('/api/payments', { authorization: 'Bearer wrongkey' });
console.assert(!r.passed, 'wrong key should fail');
console.assert(r.code === 401, '401 on bad key');
console.log('✓ wrong API key returns 401');
// No auth + no bypass + no authentik header
process.env.DEV_BYPASS_AUTH = 'false';
r = testReq('/api/payments', {});
console.assert(!r.passed && r.code === 401, 'no creds → 401');
console.log('✓ no credentials returns 401');
// Upload endpoints no longer public
r = testReq('/api/upload/csv', {});
console.assert(!r.passed && r.code === 401, 'upload/csv requires auth');
console.log('✓ /api/upload/csv now requires auth (was public, now fixed)');
// Authentik header pass-through
r = testReq('/api/payments', { 'x-authentik-username': 'lukastest', 'x-authentik-email': '[EMAIL]' });
console.assert(r.passed && r.user.username === 'lukastest', 'authentik header works');
console.log('✓ Authentik X-authentik-username header works');
console.log('\nAll auth tests passed.');
EOF
Copy code to clipboard
OUT
✓ /api/health is public
✓ valid API key passes
✓ wrong API key returns 401
✓ no credentials returns 401
✓ /api/upload/csv now requires auth (was public, now fixed)
✓ Authentik X-authentik-username header works
All auth tests passed.
All auth cases pass. Now test the MCP spending_by_tag tool against the live backend (with DEV_BYPASS_AUTH still on):
Bash
Test spending_by_tag MCP tool against live backend
IN
cd /volume2/docker/finance/finance-hub/mcp && \
printf '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}\n{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"spending_by_tag","arguments":{"dateFrom":"2026-05-01","dateTo":"2026-05-09"}}}\n' | \
FINANCE_HUB_URL=http://localhost:3001 [ENV_SECRET] \
timeout 8 node server.js 2>/dev/null | grep '"id":2' | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['result']['content'][0]['text'][:500])"
Copy code to clipboard
OUT
{
"period": {
"from": "2026-05-01",
"to": "2026-05-09"
},
"totalTransactions": 36,
"breakdown": [
{
"tag": "Bills",
"total": 117.9,
"count": 6
},
{
"tag": "(untagged)",
"total": 1153.87,
"count": 22
}
]
}
MCP tools work correctly against real data. Let me write the Claude desktop config example and the
.gitignore
for the mcp dir:
Write
claude_desktop_config.example.json
claude_desktop_config.example.json
14 lines
{
"_comment": "Add this block to ~/.config/claude/claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json)",
"mcpServers": {
"finance-hub": {
"command": "node",
"args": ["/volume2/docker/finance/finance-hub/mcp/server.js"],
"env": {
"FINANCE_HUB_URL": "http://localhost:3001",
"FINANCE_HUB_API_KEY": "94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c"
}
}
}
}
Write
.gitignore
.gitignore
2 lines
node_modules/
Update Todos
Fix auth.js: add API key support + remove upload endpoints from PUBLIC_PATHS
Update index.js: add CORS origin restriction via env var
Update .env and .env.example with API_KEY variable
Build MCP server (stdio, Claude desktop compatible)
Test: restart backend, verify API key auth and MCP connection
Now let me save relevant project context to memory:
Read
MEMORY.md
MEMORY.md
Write
MEMORY.md
MEMORY.md
4 lines
# Memory Index
- [project_finance_hub.md](project_finance_hub.md) — Finance Hub architecture, auth design, MCP server, API key setup
Write
project_finance_hub.md
project_finance_hub.md
35 lines
---
name: Finance Hub project state
description: Architecture, auth design, API key, MCP server location and tools for the finance-hub project
type: project
---
Finance Hub is a personal finance tracker at `/volume2/docker/finance/finance-hub/`.
**Running services** (as of 2026-05-09):
- Backend: port 3001 (Express/Prisma, PostgreSQL)
- Frontend: port 5175 (React/Vite)
- Adminer: port 8092
- Authentik: port 9100 (auth.lakylak.xyz, tag 2026.2.1)
**Auth design:**
- Production: NPM (Nginx Proxy Manager) + Authentik forward-auth outpost → injects `X-authentik-username` header
- `DEV_BYPASS_AUTH=true` is currently set in `.env` — app runs without real auth
- API key auth added: `Authorization: Bearer <API_KEY>` bypasses Authentik header check (used by MCP/scripts)
- API_KEY in `.env`: `94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c`
**Public endpoints** (no auth): `/api/health`, `/api/payments/ingest`
**Security fix applied (2026-05-09):** Removed `/api/upload/csv` and `/api/upload/preview` from PUBLIC_PATHS — they were incorrectly public.
**MCP server:** `/volume2/docker/finance/finance-hub/mcp/server.js`
- Stdio transport, works with Claude desktop
- Tools: list_transactions, spending_by_tag, get_transaction, list_tags, add_tag, remove_tag, health_check
- Env: FINANCE_HUB_URL, FINANCE_HUB_API_KEY
- Config example: `mcp/claude_desktop_config.example.json`
**To enable real Authentik auth:** Set `DEV_BYPASS_AUTH=false` in `.env`, configure NPM proxy host for finance-hub w...
|
[{"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) - 12 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":"12","depth":22,"bounds":{"left":0.00831117,"top":0.1452514,"width":0.003656915,"height":0.008778931},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.008643617,"top":0.14604948,"width":0.0016622341,"height":0.007980846}},{"char_start":1,"char_count":1,"bounds":{"left":0.009973404,"top":0.14604948,"width":0.0023271276,"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":"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":27,"bounds":{"left":0.10605053,"top":0.13168396,"width":0.004654255,"height":0.011173184},"on_screen":true,"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":27,"bounds":{"left":0.10605053,"top":0.14924182,"width":0.004654255,"height":0.011173184},"on_screen":true,"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":"mcp","depth":27,"bounds":{"left":0.028590426,"top":0.18355946,"width":0.008643617,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.10605053,"top":0.18435754,"width":0.004654255,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.022273935,"top":0.20111732,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"scripts","depth":27,"bounds":{"left":0.028590426,"top":0.20111732,"width":0.013630319,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.2019154,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":6,"bounds":{"left":0.030917553,"top":0.2019154,"width":0.011303191,"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","depth":27,"bounds":{"left":0.028590426,"top":0.21867518,"width":0.00831117,"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":3,"bounds":{"left":0.029920213,"top":0.21947326,"width":0.006981383,"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":".env.example","depth":27,"bounds":{"left":0.028590426,"top":0.23623304,"width":0.025930852,"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":11,"bounds":{"left":0.029920213,"top":0.23703113,"width":0.024933511,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":27,"bounds":{"left":0.10638298,"top":0.23703113,"width":0.003656915,"height":0.011173184},"on_screen":true,"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":".gitignore","depth":27,"bounds":{"left":0.028590426,"top":0.25379092,"width":0.018949468,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.254589,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":9,"bounds":{"left":0.029920213,"top":0.254589,"width":0.017952127,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":27,"bounds":{"left":0.10638298,"top":0.254589,"width":0.003656915,"height":0.011173184},"on_screen":true,"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":"docker-compose.yml","depth":27,"bounds":{"left":0.028590426,"top":0.27134877,"width":0.042220745,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.27214685,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":17,"bounds":{"left":0.03125,"top":0.27214685,"width":0.03956117,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":27,"bounds":{"left":0.10638298,"top":0.27214685,"width":0.003656915,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.021276595,"top":0.28731045,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"README.md","depth":27,"bounds":{"left":0.028590426,"top":0.28890663,"width":0.025265958,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.021276595,"top":0.3048683,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"sms_export.json","depth":27,"bounds":{"left":0.028590426,"top":0.3064645,"width":0.032912236,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.30726257,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":14,"bounds":{"left":0.030917553,"top":0.30726257,"width":0.030917553,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.019614361,"top":0.32402235,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"payments-logger","depth":27,"bounds":{"left":0.025930852,"top":0.32402235,"width":0.034574468,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.025930852,"top":0.32482043,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":14,"bounds":{"left":0.028590426,"top":0.32482043,"width":0.031914894,"height":0.011971269}}],"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.0674867,"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.18317819,"top":0.047885075,"width":0.039893616,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXRadioButton","text":".env.example, preview, Editor Group 1","depth":28,"bounds":{"left":0.22307181,"top":0.047885075,"width":0.05219415,"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.27526596,"top":0.047885075,"width":0.045877658,"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.32114363,"top":0.047885075,"width":0.04654255,"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":"sms_export.json, Editor Group 1","depth":28,"bounds":{"left":0.36768618,"top":0.047885075,"width":0.053523935,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.14527926,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextArea","text":"# ── Database ───────────────────────────────────────────────────────────────────\nDB_PASSWORD=payments_secret\n\n# ── Notifier service ──────────────────────────────────────────────────────────\nNOTIFIER_URL=https://notifier.lakylak.xyz\nNOTIFIER_CHANNEL=viber\nNOTIFY_DEFAULT_PHONE=+359000000000\n\n# ── Timezone ─────────────────────────────────────────────────────────────────\nTZ=Europe/Sofia\n\n# ── API key auth — for MCP server, scripts, iOS shortcuts on protected endpoints ──\n# Generate with: openssl rand -hex 32\nAPI_KEY=94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c\n\n# ── Dev only — set false and configure NPM+Authentik for production ──────────\n# DEV_BYPASS_AUTH=true","depth":28,"bounds":{"left":0.13763298,"top":0.4094174,"width":0.2017952,"height":0.014365523},"on_screen":true,"value":"# ── Database ───────────────────────────────────────────────────────────────────\nDB_PASSWORD=payments_secret\n\n# ── Notifier service ──────────────────────────────────────────────────────────\nNOTIFIER_URL=https://notifier.lakylak.xyz\nNOTIFIER_CHANNEL=viber\nNOTIFY_DEFAULT_PHONE=+359000000000\n\n# ── Timezone ─────────────────────────────────────────────────────────────────\nTZ=Europe/Sofia\n\n# ── API key auth — for MCP server, scripts, iOS shortcuts on protected endpoints ──\n# Generate with: openssl rand -hex 32\nAPI_KEY=94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c\n\n# ── Dev only — set false and configure NPM+Authentik for production ──────────\n# DEV_BYPASS_AUTH=true","role_description":"editor","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"# ── Database ───────────────────────────────────────────────────────────────────\nDB_PASSWORD=payments_secret\n\n# ── Notifier service ──────────────────────────────────────────────────────────\nNOTIFIER_URL=https://notifier.lakylak.xyz\nNOTIFIER_CHANNEL=viber\nNOTIFY_DEFAULT_PHONE=+359000000000\n\n# ── Timezone ─────────────────────────────────────────────────────────────────\nTZ=Europe/Sofia\n\n# ── API key auth — for MCP server, scripts, iOS shortcuts on protected endpoints ──\n# Generate with: openssl rand -hex 32\nAPI_KEY=94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c\n\n# ── Dev only — set false and configure NPM+Authentik for production ──────────\n# DEV_BYPASS_AUTH=true","depth":29,"bounds":{"left":0.13763298,"top":0.42298484,"width":0.2017952,"height":0.0007980846},"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":false,"is_expanded":false},{"role":"AXRadioButton","text":"Implement Authentik inte…, Editor Group 2","depth":28,"bounds":{"left":0.63663566,"top":0.047885075,"width":0.07446808,"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,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.008643617,"top":0.9856345,"width":0.0013297872,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.009973404,"top":0.9856345,"width":0.01462766,"height":0.011173184}}],"role_description":"text"},{"role":"AXButton","text":"finance-hub (Git) - main*, Checkout Branch/Tag...","depth":16,"bounds":{"left":0.030917553,"top":0.98244214,"width":0.019281914,"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":"main*","depth":17,"bounds":{"left":0.03723404,"top":0.9856345,"width":0.011968086,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03723404,"top":0.9856345,"width":0.0013297872,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.03856383,"top":0.9856345,"width":0.008976064,"height":0.011173184}}],"role_description":"text"},{"role":"AXButton","text":"finance-hub (Git) - Synchronize Changes","depth":16,"bounds":{"left":0.050199468,"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":"No Problems","depth":16,"bounds":{"left":0.06017287,"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.061835106,"top":0.9848364,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":17,"bounds":{"left":0.06715426,"top":0.9856345,"width":0.004986702,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.07180851,"top":0.9848364,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":17,"bounds":{"left":0.07712766,"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.08444149,"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.08610372,"top":0.9848364,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":17,"bounds":{"left":0.09142287,"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":"AXStaticText","text":"Info: Setting up SSH Host nas: Setting up SSH tunnel","depth":12,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Implement Authentik integration with security review","depth":19,"bounds":{"left":0.55984044,"top":0.08060654,"width":0.099734046,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Session history","depth":19,"bounds":{"left":0.9780585,"top":0.08060654,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"Session history","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New session","depth":19,"bounds":{"left":0.9886968,"top":0.08060654,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"New session","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Message actions","depth":24,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"README.md","depth":23,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"README.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"lets work on authentication. I want to be able to connect using authentik. REveiw copy of the project in auth folder. Lets test it and establish security. There should be simple way to reauthorize automatically for api and also there should be claude chat compatible mcp with autorization that si stable. Think about it test it and then provide suggestions","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Thinking","depth":23,"on_screen":false,"role_description":"disclosure triangle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Thinking","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Let me explore the project structure first, particularly the auth folder.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"List finance 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":"find /volume2/docker/finance -type f | head -80 && echo \"---\" && ls /volume2/docker/finance/","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/volume2/docker/finance/payments-logger/.env\n/volume2/docker/finance/payments-logger/.env.example\n/volume2/docker/finance/payments-logger/.gitignore\n/volume2/docker/finance/payments-logger/API.md\n/volume2/docker/finance/payments-logger/README.md\n/volume2/docker/finance/payments-logger/docker-compose.yml\n/volume2/docker/finance/auth/.env\n/volume2/docker/finance/auth/.env.example\n/volume2/docker/finance/auth/README.md\n/volume2/docker/finance/auth/docker-compose.yml\n/volume2/docker/finance/dsk-uploader/.gitignore\n/volume2/docker/finance/dsk-uploader/README.md\n/volume2/docker/finance/dsk-uploader/USAGE.md\n/volume2/docker/finance/dsk-uploader/app.py\n/volume2/docker/finance/dsk-uploader/app_flask.py\n/volume2/docker/finance/dsk-uploader/dskuploader.py\n/volume2/docker/finance/dsk-uploader/requirements.txt\n/volume2/docker/finance/dsk-uploader/.env\n/volume2/docker/finance/dsk-uploader/.env.example\n/volume2/docker/finance/dsk-uploader/Dockerfile\n/volume2/docker/finance/dsk-uploader/docker-compose.yml\n/volume2/docker/finance/dsk-uploader/.dockerignore\n/volume2/docker/finance/finance-hub/.env.example\n/volume2/docker/finance/finance-hub/.gitignore\n/volume2/docker/finance/finance-hub/.env\n/volume2/docker/finance/finance-hub/docker-compose.yml\n/volume2/docker/finance/finance-hub/sms_export.json\n/volume2/docker/finance/finance-hub/README.md\n/volume2/docker/finance/payments-logger/.claude/settings.local.json\n/volume2/docker/finance/payments-logger/backend/.dockerignore\n/volume2/docker/finance/payments-logger/backend/Dockerfile\n/volume2/docker/finance/payments-logger/backend/package.json\n/volume2/docker/finance/finance-hub/backend/package.json\n/volume2/docker/finance/finance-hub/backend/Dockerfile\n/volume2/docker/finance/finance-hub/frontend/package.json\n/volume2/docker/finance/finance-hub/frontend/Dockerfile\n/volume2/docker/finance/finance-hub/frontend/vite.config.js\n/volume2/docker/finance/finance-hub/frontend/tailwind.config.js\n/volume2/docker/finance/finance-hub/frontend/postcss.config.js\n/volume2/docker/finance/finance-hub/frontend/index.html\n/volume2/docker/finance/finance-hub/scripts/reimport_sms.sh\n/volume2/docker/finance/finance-hub/.git/description\n/volume2/docker/finance/finance-hub/.git/HEAD\n/volume2/docker/finance/finance-hub/.git/COMMIT_EDITMSG\n/volume2/docker/finance/finance-hub/.git/index\n/volume2/docker/finance/finance-hub/.git/hooks/post-update.sample\n/volume2/docker/finance/finance-hub/.git/hooks/pre-applypatch.sample\n/volume2/docker/finance/finance-hub/.git/hooks/pre-commit.sample\n/volume2/docker/finance/finance-hub/.git/hooks/applypatch-msg.sample\n/volume2/docker/finance/finance-hub/.git/hooks/pre-rebase.sample\n/volume2/docker/finance/finance-hub/.git/hooks/pre-merge-commit.sample\n/volume2/docker/finance/finance-hub/.git/hooks/update.sample\n/volume2/docker/finance/finance-hub/.git/hooks/pre-push.sample\n/volume2/docker/finance/finance-hub/.git/hooks/push-to-checkout.sample\n/volume2/docker/finance/finance-hub/.git/hooks/prepare-commit-msg.sample\n/volume2/docker/finance/finance-hub/.git/hooks/commit-msg.sample\n/volume2/docker/finance/finance-hub/.git/hooks/pre-receive.sample\n/volume2/docker/finance/finance-hub/.git/hooks/fsmonitor-watchman.sample\n/volume2/docker/finance/finance-hub/.git/logs/HEAD\n/volume2/docker/finance/payments-logger/frontend/.dockerignore\n/volume2/docker/finance/payments-logger/frontend/Dockerfile\n/volume2/docker/finance/payments-logger/frontend/index.html\n/volume2/docker/finance/payments-logger/frontend/package.json\n/volume2/docker/finance/payments-logger/frontend/postcss.config.js\n/volume2/docker/finance/payments-logger/frontend/tailwind.config.js\n/volume2/docker/finance/payments-logger/frontend/vite.config.js\n/volume2/docker/finance/finance-hub/.git/config\n/volume2/docker/finance/payments-logger/auth/.env\n/volume2/docker/finance/payments-logger/auth/.env.example\n/volume2/docker/finance/payments-logger/auth/README.md\n/volume2/docker/finance/auth/auth/.env\n/volume2/docker/finance/auth/auth/.env.example\n/volume2/docker/finance/auth/auth/docker-compose.yml\n/volume2/docker/finance/auth/auth/README.md\n/volume2/docker/finance/dsk-uploader/.git/description\n/volume2/docker/finance/dsk-uploader/.git/packed-refs\n/volume2/docker/finance/dsk-uploader/.git/HEAD\n/volume2/docker/finance/dsk-uploader/.git/FETCH_HEAD\n/volume2/docker/finance/dsk-uploader/.git/index\n/volume2/docker/finance/dsk-uploader/.git/COMMIT_EDITMSG\n---\nauth\ndsk-uploader\nfinance-hub\npayments-logger","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"README.md","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"README.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"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 dive into the auth folder and the existing backend auth setup.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"README.md","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"README.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"docker-compose.yml","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"docker-compose.yml","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read auth env examples and nested auth config","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"cat /volume2/docker/finance/auth/.env.example && echo \"===\" && cat /volume2/docker/finance/auth/auth/.env.example 2>/dev/null && echo \"===\" && cat /volume2/docker/finance/auth/auth/docker-compose.yml 2>/dev/null","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":"# Copy this file to .env and fill in all values before starting\n\n# ── Image versions ───────────────────────────────────────────────────────────\n# Pinned tag applied to server, worker, AND outpost — they must always match.\n# To upgrade: change this one value and run: docker compose pull && docker compose up -d\n# Check releases: https://github.com/goauthentik/authentik/releases\nAUTHENTIK_TAG=2026.2.1\n\n# ── Database ──────────────────────────────────────────────────────────────────\n# Strong password for the PostgreSQL authentik database\n# Used by the postgres container and all authentik services\nPG_PASS=\n\n# ── Authentik core ────────────────────────────────────────────────────────────\n# Cryptographic secret — NEVER share or commit this\n# Generate with: openssl rand -base64 36\nAUTHENTIK_SECRET_KEY=\n\n# Full public HTTPS URL where authentik is reachable\n# Must match the domain you configure in NPM\n# Used for OAuth redirects and by the outpost to contact the server\nAUTHENTIK_HOST=https://auth.lakylak.xyz\n\n# ── Bootstrap (first-start only) ─────────────────────────────────────────────\n# If set, authentik creates this admin account automatically on first boot.\n# You can leave these empty and use the /if/flow/initial-setup/ URL instead.\nAUTHENTIK_BOOTSTRAP_EMAIL=you@example.com\nAUTHENTIK_BOOTSTRAP_PASSWORD=\n\n# ── Outpost ───────────────────────────────────────────────────────────────────\n# Token for the proxy outpost container.\n# Leave as \"placeholder\" on first deploy — the outpost will fail to connect\n# until you create it in the UI and paste the real token here (see README step 6).\nAUTHENTIK_OUTPOST_TOKEN=placeholder\n===\n# Copy this file to .env and fill in all values before starting\n\n# ── Image versions ───────────────────────────────────────────────────────────\n# Pinned tag applied to server, worker, AND outpost — they must always match.\n# To upgrade: change this one value and run: docker compose pull && docker compose up -d\n# Check releases: https://github.com/goauthentik/authentik/releases\nAUTHENTIK_TAG=2026.2.1\n\n# ── Database ──────────────────────────────────────────────────────────────────\n# Strong password for the PostgreSQL authentik database\n# Used by the postgres container and all authentik services\nPG_PASS=\n\n# ── Authentik core ────────────────────────────────────────────────────────────\n# Cryptographic secret — NEVER share or commit this\n# Generate with: openssl rand -base64 36\nAUTHENTIK_SECRET_KEY=\n\n# Full public HTTPS URL where authentik is reachable\n# Must match the domain you configure in NPM\n# Used for OAuth redirects and by the outpost to contact the server\nAUTHENTIK_HOST=https://auth.lakylak.xyz\n\n# ── Bootstrap (first-start only) ─────────────────────────────────────────────\n# If set, authentik creates this admin account automatically on first boot.\n# You can leave these empty and use the /if/flow/initial-setup/ URL instead.\nAUTHENTIK_BOOTSTRAP_EMAIL=you@example.com\nAUTHENTIK_BOOTSTRAP_PASSWORD=\n\n# ── Outpost ───────────────────────────────────────────────────────────────────\n# Token for the proxy outpost container.\n# Leave as \"placeholder\" on first deploy — the outpost will fail to connect\n# until you create it in the UI and paste the real token here (see README step 6).\nAUTHENTIK_OUTPOST_TOKEN=placeholder\n===\nservices:\n\n postgresql:\n image: docker.io/library/postgres:16-alpine\n container_name: Authentik-DB\n hostname: authentik-db\n restart: unless-stopped\n security_opt:\n - no-new-privileges:true\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -d ${POSTGRES_DB:-authentik} -U ${POSTGRES_USER:-authentik}\"]\n interval: 5s\n timeout: 5s\n retries: 5\n environment:\n POSTGRES_PASSWORD: ${PG_PASS}\n POSTGRES_USER: authentik\n POSTGRES_DB: authentik\n volumes:\n - /volume2/docker/auth/db:/var/lib/postgresql/data\n networks:\n - authentik_internal\n\n redis:\n image: docker.io/library/redis:alpine\n container_name: Authentik-REDIS\n hostname: authentik-redis\n restart: unless-stopped\n security_opt:\n - no-new-privileges:true\n healthcheck:\n test: [\"CMD-SHELL\", \"redis-cli ping | grep PONG\"]\n interval: 5s\n timeout: 3s\n retries: 5\n networks:\n - authentik_internal\n\n server:\n image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG}\n container_name: Authentik-Server\n hostname: authentik-server\n restart: unless-stopped\n command: server\n environment:\n AUTHENTIK_REDIS__HOST: authentik-redis\n AUTHENTIK_POSTGRESQL__HOST: authentik-db\n AUTHENTIK_POSTGRESQL__USER: authentik\n AUTHENTIK_POSTGRESQL__NAME: authentik\n AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}\n AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}\n AUTHENTIK_ERROR_REPORTING__ENABLED: \"false\"\n AUTHENTIK_HOST: ${AUTHENTIK_HOST}\n AUTHENTIK_BOOTSTRAP_EMAIL: ${AUTHENTIK_BOOTSTRAP_EMAIL}\n AUTHENTIK_BOOTSTRAP_PASSWORD: ${AUTHENTIK_BOOTSTRAP_PASSWORD}\n ports:\n - \"9100:9000\"\n volumes:\n - /volume2/docker/auth/media:/media\n - /volume2/docker/auth/templates:/templates\n depends_on:\n postgresql:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - authentik_internal\n - proxy\n\n worker:\n image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG}\n container_name: Authentik-Worker\n hostname: authentik-worker\n restart: unless-stopped\n command: worker\n user: root\n environment:\n AUTHENTIK_REDIS__HOST: authentik-redis\n AUTHENTIK_POSTGRESQL__HOST: authentik-db\n AUTHENTIK_POSTGRESQL__USER: authentik\n AUTHENTIK_POSTGRESQL__NAME: authentik\n AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}\n AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}\n volumes:\n - /var/run/docker.sock:/var/run/docker.sock\n - /volume2/docker/auth/media:/media\n - /volume2/docker/auth/certs:/certs\n - /volume2/docker/auth/templates:/templates\n depends_on:\n postgresql:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - authentik_internal\n\n outpost:\n image: ghcr.io/goauthentik/proxy:${AUTHENTIK_TAG}\n container_name: Authentik-Outpost\n hostname: authentik-outpost\n restart: unless-stopped\n environment:\n AUTHENTIK_HOST: ${AUTHENTIK_HOST}\n AUTHENTIK_INSECURE: \"false\"\n AUTHENTIK_TOKEN: ${AUTHENTIK_OUTPOST_TOKEN}\n ports:\n - \"9101:9000\"\n depends_on:\n - server\n networks:\n - authentik_internal\n - proxy\n\nnetworks:\n authentik_internal:\n internal: true\n proxy:\n external: true","depth":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 look at the backend auth code and the current services.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"List backend and frontend source files","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"find /volume2/docker/finance/finance-hub/backend -type f | sort && echo \"===\" && find /volume2/docker/finance/finance-hub/frontend/src -type f | sort 2>/dev/null || find /volume2/docker/finance/finance-hub/frontend -type f | sort","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/volume2/docker/finance/finance-hub/backend/Dockerfile\n/volume2/docker/finance/finance-hub/backend/package.json\n/volume2/docker/finance/finance-hub/backend/prisma/migrations/20260508_init/migration.sql\n/volume2/docker/finance/finance-hub/backend/prisma/migrations/20260509_refactor/migration.sql\n/volume2/docker/finance/finance-hub/backend/prisma/migrations/migration_lock.toml\n/volume2/docker/finance/finance-hub/backend/prisma/schema.prisma\n/volume2/docker/finance/finance-hub/backend/src/auth.js\n/volume2/docker/finance/finance-hub/backend/src/csvParser.js\n/volume2/docker/finance/finance-hub/backend/src/index.js\n/volume2/docker/finance/finance-hub/backend/src/parser.js\n/volume2/docker/finance/finance-hub/backend/src/routes/payments.js\n/volume2/docker/finance/finance-hub/backend/src/routes/upload.js\n/volume2/docker/finance/finance-hub/backend/src/utils/linkTransaction.js\n/volume2/docker/finance/finance-hub/backend/src/utils/recipientTags.js\n===\n/volume2/docker/finance/finance-hub/frontend/src/App.jsx\n/volume2/docker/finance/finance-hub/frontend/src/components/FilterBar.jsx\n/volume2/docker/finance/finance-hub/frontend/src/components/PaymentCard.jsx\n/volume2/docker/finance/finance-hub/frontend/src/components/PaymentList.jsx\n/volume2/docker/finance/finance-hub/frontend/src/components/PaymentTable.jsx\n/volume2/docker/finance/finance-hub/frontend/src/components/SettingsPanel.jsx\n/volume2/docker/finance/finance-hub/frontend/src/components/UploadPanel.jsx\n/volume2/docker/finance/finance-hub/frontend/src/hooks/useSettings.js\n/volume2/docker/finance/finance-hub/frontend/src/index.css\n/volume2/docker/finance/finance-hub/frontend/src/main.jsx","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Check running Docker containers","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"docker ps --format \"table {{.Names}}\\t{{.Status}}\\t{{.Ports}}\" 2>/dev/null | head -30","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(Bash completed with no output)","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"auth.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"auth.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"index.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"index.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Check all Docker containers","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"docker ps -a --format \"table {{.Names}}\\t{{.Status}}\\t{{.Ports}}\" 2>/dev/null","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":"Exit code 1","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":".env","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":".env","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":".env","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":".env","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"docker-compose.yml","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"docker-compose.yml","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Thinking","depth":23,"on_screen":false,"role_description":"disclosure triangle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Thinking","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"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":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Check status of auth and finance-hub Docker services","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"cd /volume2/docker/finance/auth && docker compose ps 2>/dev/null || echo \"NOT RUNNING\"\necho \"===\"\ncd /volume2/docker/finance/finance-hub && docker compose ps 2>/dev/null || echo \"NOT RUNNING\"","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":"NOT RUNNING\n===\nNOT RUNNING","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":"Let me check a few more details before forming recommendations.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"README.md","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"README.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Check payments-logger auth config","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"cat /volume2/docker/finance/payments-logger/auth/.env.example 2>/dev/null && echo \"===\" && cat /volume2/docker/finance/payments-logger/auth/.env 2>/dev/null","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":"# Copy this file to .env and fill in all values before starting\n\n# ── Image versions ───────────────────────────────────────────────────────────\n# Pinned tag applied to server, worker, AND outpost — they must always match.\n# To upgrade: change this one value and run: docker compose pull && docker compose up -d\n# Check releases: https://github.com/goauthentik/authentik/releases\nAUTHENTIK_TAG=2026.2.1\n\n# ── Database ──────────────────────────────────────────────────────────────────\n# Strong password for the PostgreSQL authentik database\n# Used by the postgres container and all authentik services\nPG_PASS=\n\n# ── Authentik core ────────────────────────────────────────────────────────────\n# Cryptographic secret — NEVER share or commit this\n# Generate with: openssl rand -base64 36\nAUTHENTIK_SECRET_KEY=\n\n# Full public HTTPS URL where authentik is reachable\n# Must match the domain you configure in NPM\n# Used for OAuth redirects and by the outpost to contact the server\nAUTHENTIK_HOST=https://auth.lakylak.xyz\n\n# ── Bootstrap (first-start only) ─────────────────────────────────────────────\n# If set, authentik creates this admin account automatically on first boot.\n# You can leave these empty and use the /if/flow/initial-setup/ URL instead.\nAUTHENTIK_BOOTSTRAP_EMAIL=you@example.com\nAUTHENTIK_BOOTSTRAP_PASSWORD=\n\n# ── Outpost ───────────────────────────────────────────────────────────────────\n# Token for the proxy outpost container.\n# Leave as \"placeholder\" on first deploy — the outpost will fail to connect\n# until you create it in the UI and paste the real token here (see README step 6).\nAUTHENTIK_OUTPOST_TOKEN=placeholder\n===\n# Authentik image tag — applies to server, worker, AND outpost (must all match)\n# Check latest: https://github.com/goauthentik/authentik/releases\n# Example: 2024.12.3\nAUTHENTIK_TAG=2026.2.1\n\n# PostgreSQL password — used by both postgres and authentik server/worker\nPG_PASS=Og8L5@a1QA6u\n\n# Secret key — generate with: openssl rand -base64 36\nAUTHENTIK_SECRET_KEY=Uq6Mc2oI6zeWtoZcCy+Dw+IdNJ80yIMZk5ZgsP/tYmopFmhB/RHxbN7TNFZDNR1wrao=\n\n# Public URL authentik is reachable at (used for redirects and the outpost)\nAUTHENTIK_HOST=https://auth.lakylak.xyz\n\n# Bootstrap admin account created on first start (can be left empty to set via UI)\nAUTHENTIK_BOOTSTRAP_EMAIL=kovaliklukas@proton.me\nAUTHENTIK_BOOTSTRAP_PASSWORD=3bAc4Jcs\n\n# Outpost token — leave as placeholder until you create the outpost in the Authentik UI\n# See README.md step 6 for how to get this value\nAUTHENTIK_OUTPOST_TOKEN=H7Ppl2ps6h6e1mJ0CwXXoklQScbFJ1gT5WYXErtaRRQz5ukWfES78OXLVz6S","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Test if Authentik and finance backend are reachable","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"curl -s --max-time 3 http://localhost:9100/api/v3/core/applications/ 2>/dev/null | head -20 || echo \"Authentik not reachable on 9100\"\ncurl -s --max-time 3 http://localhost:3001/api/health 2>/dev/null | head -5 || echo \"Finance backend not reachable on 3001\"","depth":26,"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":"{\"detail\":\"Authentication credentials were not provided.\"}{\"status\":\"ok\",\"timestamp\":\"2026-05-09T16:02:54.094Z\",\"storage\":{\"type\":\"PostgreSQL\",\"host\":\"db\",\"database\":\"finance_hub\"}}","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":"Both Authentik (port 9100) and finance backend (port 3001) are running. Let me test the actual auth state and check CORS config.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Test backend auth bypass and Authentik health","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# Test that backend accepts requests without auth (DEV_BYPASS_AUTH=true)\ncurl -s http://localhost:3001/api/payments?limit=1 | python3 -c \"import sys,json; d=json.load(sys.stdin); print('AUTH BYPASS ACTIVE - got', d.get('total','?'), 'records')\" 2>/dev/null || echo \"Error parsing\"\n\n# Test Authentik health\ncurl -s --max-time 3 http://localhost:9100/-/health/ready/ && echo \"Authentik ready\"","depth":26,"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":"AUTH BYPASS ACTIVE - got 235 records\nAuthentik ready","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"payments.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"payments.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Thinking","depth":23,"on_screen":false,"role_description":"disclosure triangle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Thinking","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Good picture. Let me now check the latest MCP SDK version before building.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Check MCP SDK latest version and node version","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"npm view @modelcontextprotocol/sdk version 2>/dev/null && node --version","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":"Exit code 127","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Verify public path configuration","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# Check if the upload endpoints are really public\ngrep -n 'PUBLIC_PATHS\\|upload\\|ingest' /volume2/docker/finance/finance-hub/backend/src/auth.js","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":"<tool_use_error>Cancelled: parallel tool call Bash(npm view @modelcontextprotocol/sdk versi…) errored</tool_use_error>","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Check node version and MCP SDK latest","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"node --version 2>/dev/null && python3 -c \"import urllib.request; import json; d=json.loads(urllib.request.urlopen('https://registry.npmjs.org/@modelcontextprotocol/sdk/latest').read()); print(d['version'])\" 2>/dev/null || echo \"no npm/network\"","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":"v18.20.4\n1.29.0","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":"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":"Fix auth.js: add API key support + remove upload endpoints from PUBLIC_PATHS","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update index.js: add CORS origin restriction via env var","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update .env and .env.example with API_KEY variable","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Build MCP server (stdio, Claude desktop compatible)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Test: restart backend, verify API key auth and MCP connection","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Edit","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"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":"Added 18 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update Todos","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Fix auth.js: add API key support + remove upload endpoints from PUBLIC_PATHS","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update index.js: add CORS origin restriction via env var","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update .env and .env.example with API_KEY variable","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Build MCP server (stdio, Claude desktop compatible)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Test: restart backend, verify API key auth and MCP connection","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Edit","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"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":"Added 3 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update Todos","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Fix auth.js: add API key support + remove upload endpoints from PUBLIC_PATHS","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update index.js: add CORS origin restriction via env var","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update .env and .env.example with API_KEY variable","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Build MCP server (stdio, Claude desktop compatible)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Test: restart backend, verify API key auth and MCP connection","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Generate a secure API key","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"openssl rand -hex 32","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":"94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Edit","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":".env","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":".env","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Added 4 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":".env.example","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":".env.example","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Edit","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":".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":"Added 12 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Also need to pass","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"API_KEY","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"and","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CORS_ORIGIN","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"through docker-compose:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Edit","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"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":"Added 3 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update Todos","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Fix auth.js: add API key support + remove upload endpoints from PUBLIC_PATHS","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update index.js: add CORS origin restriction via env var","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update .env and .env.example with API_KEY variable","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Build MCP server (stdio, Claude desktop compatible)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Test: restart backend, verify API key auth and MCP connection","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Now building the MCP server:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Create MCP directory","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/mcp && ls /volume2/docker/finance/finance-hub/mcp","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(Bash completed with no output)","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"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":"17 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"{\n \"name\": \"finance-hub-mcp\",\n \"version\": \"1.0.0\",\n \"description\": \"MCP server for Finance Hub — exposes transaction tools to Claude\",\n \"main\": \"server.js\",\n \"type\": \"module\",\n \"scripts\": {\n \"start\": \"node server.js\"\n },\n \"dependencies\": {\n \"@modelcontextprotocol/sdk\": \"^1.29.0\"\n },\n \"engines\": {\n \"node\": \">=18\"\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":"server.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"server.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"236 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\n\nconst BASE_URL = (process.env.FINANCE_HUB_URL || 'http://localhost:3001').replace(/\\/$/, '');\nconst API_KEY = process.env.FINANCE_HUB_API_KEY;\n\nif (!API_KEY) {\n process.stderr.write('Warning: FINANCE_HUB_API_KEY not set — requests will fail if DEV_BYPASS_AUTH is off\\n');\n}\n\n// ── HTTP helper ───────────────────────────────────────────────────────────────\n\nasync function api(path, opts = {}) {\n const headers = { 'Content-Type': 'application/json' };\n if (API_KEY) headers['Authorization'] = `Bearer ${API_KEY}`;\n\n const res = await fetch(`${BASE_URL}${path}`, {\n ...opts,\n headers: { ...headers, ...(opts.headers || {}) },\n });\n\n if (res.status === 204) return null;\n const body = await res.text();\n if (!res.ok) throw new Error(`HTTP ${res.status}: ${body}`);\n return body ? JSON.parse(body) : null;\n}\n\n// ── Tool definitions ──────────────────────────────────────────────────────────\n\nconst TOOLS = [\n {\n name: 'list_transactions',\n description:\n 'List finance transactions with optional filters. Returns paginated results including total amount for the filtered set.',\n inputSchema: {\n type: 'object',\n properties: {\n page: { type: 'number', description: 'Page number (default 1)' },\n limit: { type: 'number', description: 'Results per page, max 200 (default 50)' },\n dateFrom: { type: 'string', description: 'Start date YYYY-MM-DD (inclusive)' },\n dateTo: { type: 'string', description: 'End date YYYY-MM-DD (inclusive)' },\n tag: { type: 'string', description: 'Filter by tag name' },\n recipient: { type: 'string', description: 'Substring match on payee name' },\n type: { type: 'string', description: 'Transaction type: POS | ATM | WALLET' },\n source: { type: 'string', description: 'Import source: INGEST | UPLOAD' },\n search: { type: 'string', description: 'Full-text search across rawMessage and recipient' },\n hideBalanceAlerts: { type: 'boolean', description: 'Exclude balance-notification SMS (default false)' },\n sortBy: { type: 'string', description: 'Sort field: date | amount | recipient | createdAt' },\n sortDir: { type: 'string', description: 'asc or desc (default desc)' },\n },\n },\n },\n {\n name: 'spending_by_tag',\n description:\n 'Aggregate spending totals by tag for a date range. Fetches up to 200 transactions and groups them. Good for monthly summaries.',\n inputSchema: {\n type: 'object',\n properties: {\n dateFrom: { type: 'string', description: 'Start date YYYY-MM-DD' },\n dateTo: { type: 'string', description: 'End date YYYY-MM-DD' },\n },\n },\n },\n {\n name: 'get_transaction',\n description: 'Get a single transaction by its numeric ID.',\n inputSchema: {\n type: 'object',\n required: ['id'],\n properties: {\n id: { type: 'number', description: 'Transaction import ID' },\n },\n },\n },\n {\n name: 'list_tags',\n description: 'List all available tags with their colors.',\n inputSchema: { type: 'object', properties: {} },\n },\n {\n name: 'add_tag',\n description: 'Add a tag to a transaction. Creates the tag globally if it does not exist.',\n inputSchema: {\n type: 'object',\n required: ['id', 'name'],\n properties: {\n id: { type: 'number', description: 'Transaction ID' },\n name: { type: 'string', description: 'Tag name (e.g. \"Groceries\")' },\n color: { type: 'string', description: 'Hex color (e.g. \"#22c55e\"). Optional — auto-assigned if omitted.' },\n },\n },\n },\n {\n name: 'remove_tag',\n description: 'Remove a tag from a transaction.',\n inputSchema: {\n type: 'object',\n required: ['id', 'tagId'],\n properties: {\n id: { type: 'number', description: 'Transaction ID' },\n tagId: { type: 'number', description: 'Tag ID (from list_tags or the transaction object)' },\n },\n },\n },\n {\n name: 'health_check',\n description: 'Check Finance Hub backend connectivity and database status.',\n inputSchema: { type: 'object', properties: {} },\n },\n];\n\n// ── Server setup ──────────────────────────────────────────────────────────────\n\nconst server = new Server(\n { name: 'finance-hub', version: '1.0.0' },\n { capabilities: { tools: {} } },\n);\n\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));\n\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args = {} } = request.params;\n\n try {\n switch (name) {\n\n case 'list_transactions': {\n const params = new URLSearchParams();\n for (const [k, v] of Object.entries(args)) {\n if (v !== undefined && v !== null && v !== '') params.set(k, String(v));\n }\n const data = await api(`/api/payments?${params}`);\n return text(JSON.stringify({\n total: data.total,\n page: data.page,\n limit: data.limit,\n totalAmount: data.totalAmount,\n transactions: data.payments,\n }, null, 2));\n }\n\n case 'spending_by_tag': {\n const params = new URLSearchParams({ limit: '200', hideBalanceAlerts: 'true' });\n if (args.dateFrom) params.set('dateFrom', args.dateFrom);\n if (args.dateTo) params.set('dateTo', args.dateTo);\n\n const data = await api(`/api/payments?${params}`);\n\n const byTag = {};\n let untaggedTotal = 0, untaggedCount = 0;\n\n for (const tx of data.payments) {\n const amount = tx.amount ?? 0;\n if (!tx.tags?.length) {\n untaggedTotal += amount;\n untaggedCount++;\n } else {\n for (const tag of tx.tags) {\n if (!byTag[tag.name]) byTag[tag.name] = { total: 0, count: 0 };\n byTag[tag.name].total += amount;\n byTag[tag.name].count++;\n }\n }\n }\n\n const breakdown = Object.entries(byTag)\n .map(([tag, s]) => ({ tag, total: round2(s.total), count: s.count }))\n .sort((a, b) => b.total - a.total);\n\n if (untaggedCount) breakdown.push({ tag: '(untagged)', total: round2(untaggedTotal), count: untaggedCount });\n\n return text(JSON.stringify({\n period: { from: args.dateFrom ?? null, to: args.dateTo ?? null },\n totalTransactions: data.total,\n note: data.total > 200 ? `Only first 200 of ${data.total} transactions included — refine the date range for full accuracy` : undefined,\n breakdown,\n }, null, 2));\n }\n\n case 'get_transaction': {\n const data = await api(`/api/payments/${args.id}`);\n return text(JSON.stringify(data, null, 2));\n }\n\n case 'list_tags': {\n const data = await api('/api/payments/meta/tags');\n return text(JSON.stringify(data, null, 2));\n }\n\n case 'add_tag': {\n const data = await api(`/api/payments/${args.id}/tags`, {\n method: 'POST',\n body: JSON.stringify({ name: args.name, color: args.color }),\n });\n return text(JSON.stringify(data, null, 2));\n }\n\n case 'remove_tag': {\n await api(`/api/payments/${args.id}/tags/${args.tagId}`, { method: 'DELETE' });\n return text('Tag removed successfully');\n }\n\n case 'health_check': {\n const data = await api('/api/health');\n return text(JSON.stringify(data, null, 2));\n }\n\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n } catch (err) {\n return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };\n }\n});\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction text(str) {\n return { content: [{ type: 'text', text: str }] };\n}\n\nfunction round2(n) {\n return Math.round(n * 100) / 100;\n}\n\n// ── Entry point ───────────────────────────────────────────────────────────────\n\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\nprocess.stderr.write(`Finance Hub MCP server connected to ${BASE_URL}\\n`);","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Now install the MCP SDK and test it:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Install MCP SDK dependencies","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"cd /volume2/docker/finance/finance-hub/mcp && node --version && npm install --save-exact 2>&1 | tail -5","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":"v18.20.4\n/bin/bash: line 1: npm: command not found","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Locate npm","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"which npm || find /usr -name npm 2>/dev/null | head -5 || find /usr/local -name npm 2>/dev/null | head -5 || ls /root/.nvm/versions/node/ 2>/dev/null","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(Bash completed with no output)","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Check system info","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ls /proc/1/exe 2>/dev/null && cat /proc/version && uname -a","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":"Exit code 2","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Find npm via Docker","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"find /volume2 /opt /home -name npm -type f 2>/dev/null | head -5\ndocker run --rm node:18-alpine node --version 2>/dev/null | head -1","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":"/home/Adm1n/.nvm/versions/node/v24.14.1/lib/node_modules/corepack/shims/npm\n/home/Adm1n/.nvm/versions/node/v24.14.1/lib/node_modules/npm/bin/npm\n/home/Adm1n/.nvm/versions/node/v24.14.1/lib/node_modules/corepack/shims/nodewin/npm","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Install MCP SDK via located npm","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/home/Adm1n/.nvm/versions/node/v24.14.1/lib/node_modules/npm/bin/npm-cli.js install --save-exact 2>&1 | tail -5","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":"28 packages are looking for funding\n run `npm fund` for details\n\nfound 0 vulnerabilities","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Verify MCP package installed","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ls && cat package.json | python3 -c \"import json,sys; d=json.load(sys.stdin); print(d['dependencies'])\"","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":"node_modules\npackage.json\npackage-lock.json\nserver.js\n{'@modelcontextprotocol/sdk': '^1.29.0'}","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. Now let me test the MCP server can at least start and call the health check:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Smoke test MCP server startup","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FINANCE_HUB_URL=http://localhost:3001 FINANCE_HUB_API_KEY=94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c \\\n echo '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\",\"params\":{}}' | timeout 5 node server.js 2>/dev/null | head -3 || echo \"NODE test (expected timeout on stdin wait)\"","depth":26,"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":"{\"result\":{\"tools\":[{\"name\":\"list_transactions\",\"description\":\"List finance transactions with optional filters. Returns paginated results including total amount for the filtered set.\",\"inputSchema\":{\"type\":\"object\",\"properties\":{\"page\":{\"type\":\"number\",\"description\":\"Page number (default 1)\"},\"limit\":{\"type\":\"number\",\"description\":\"Results per page, max 200 (default 50)\"},\"dateFrom\":{\"type\":\"string\",\"description\":\"Start date YYYY-MM-DD (inclusive)\"},\"dateTo\":{\"type\":\"string\",\"description\":\"End date YYYY-MM-DD (inclusive)\"},\"tag\":{\"type\":\"string\",\"description\":\"Filter by tag name\"},\"recipient\":{\"type\":\"string\",\"description\":\"Substring match on payee name\"},\"type\":{\"type\":\"string\",\"description\":\"Transaction type: POS | ATM | WALLET\"},\"source\":{\"type\":\"string\",\"description\":\"Import source: INGEST | UPLOAD\"},\"search\":{\"type\":\"string\",\"description\":\"Full-text search across rawMessage and recipient\"},\"hideBalanceAlerts\":{\"type\":\"boolean\",\"description\":\"Exclude balance-notification SMS (default false)\"},\"sortBy\":{\"type\":\"string\",\"description\":\"Sort field: date | amount | recipient | createdAt\"},\"sortDir\":{\"type\":\"string\",\"description\":\"asc or desc (default desc)\"}}}},{\"name\":\"spending_by_tag\",\"description\":\"Aggregate spending totals by tag for a date range. Fetches up to 200 transactions and groups them. Good for monthly summaries.\",\"inputSchema\":{\"type\":\"object\",\"properties\":{\"dateFrom\":{\"type\":\"string\",\"description\":\"Start date YYYY-MM-DD\"},\"dateTo\":{\"type\":\"string\",\"description\":\"End date YYYY-MM-DD\"}}}},{\"name\":\"get_transaction\",\"description\":\"Get a single transaction by its numeric ID.\",\"inputSchema\":{\"type\":\"object\",\"required\":[\"id\"],\"properties\":{\"id\":{\"type\":\"number\",\"description\":\"Transaction import ID\"}}}},{\"name\":\"list_tags\",\"description\":\"List all available tags with their colors.\",\"inputSchema\":{\"type\":\"object\",\"properties\":{}}},{\"name\":\"add_tag\",\"description\":\"Add a tag to a transaction. Creates the tag globally if it does not exist.\",\"inputSchema\":{\"type\":\"object\",\"required\":[\"id\",\"name\"],\"properties\":{\"id\":{\"type\":\"number\",\"description\":\"Transaction ID\"},\"name\":{\"type\":\"string\",\"description\":\"Tag name (e.g. \\\"Groceries\\\")\"},\"color\":{\"type\":\"string\",\"description\":\"Hex color (e.g. \\\"#22c55e\\\"). Optional — auto-assigned if omitted.\"}}}},{\"name\":\"remove_tag\",\"description\":\"Remove a tag from a transaction.\",\"inputSchema\":{\"type\":\"object\",\"required\":[\"id\",\"tagId\"],\"properties\":{\"id\":{\"type\":\"number\",\"description\":\"Transaction ID\"},\"tagId\":{\"type\":\"number\",\"description\":\"Tag ID (from list_tags or the transaction object)\"}}}},{\"name\":\"health_check\",\"description\":\"Check Finance Hub backend connectivity and database status.\",\"inputSchema\":{\"type\":\"object\",\"properties\":{}}}]},\"jsonrpc\":\"2.0\",\"id\":1}","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":"MCP server responds correctly. Now test an actual tool call:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Test MCP health_check tool against live backend","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\\\n printf '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\",\"params\":{}}\\n{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/call\",\"params\":{\"name\":\"health_check\",\"arguments\":{}}}\\n' | \\\n FINANCE_HUB_URL=http://localhost:3001 FINANCE_HUB_API_KEY=94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c \\\n timeout 5 node server.js 2>/dev/null | tail -1 | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d['result']['content'][0]['text'])\"","depth":26,"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":"{\n \"status\": \"ok\",\n \"timestamp\": \"2026-05-09T16:19:09.977Z\",\n \"storage\": {\n \"type\": \"PostgreSQL\",\n \"host\": \"db\",\n \"database\": \"finance_hub\"\n }\n}","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Rebuild backend with API key auth changes","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# Test the API key auth directly against the backend (backend still has DEV_BYPASS_AUTH=true, need to restart first)\n# First rebuild with the new code\ncd /volume2/docker/finance/finance-hub && docker compose up -d --build backend 2>&1 | tail -8","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":"time=\"2026-05-09T19:19:13+03:00\" level=warning msg=\"/volume2/docker/finance/finance-hub/docker-compose.yml: `version` is obsolete\"\npermission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get \"http://%2Fvar%2Frun%2Fdocker.sock/v1.45/containers/json?all=1&filters=%7B%22label%22%3A%7B%22com.docker.compose.config-hash%22%3Atrue%2C%22com.docker.compose.project%3Dfinance-hub%22%3Atrue%7D%7D\": dial unix /var/run/docker.sock: connect: permission denied","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Rebuild backend with sudo","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"sudo docker compose -f /volume2/docker/finance/finance-hub/docker-compose.yml up -d --build backend 2>&1 | tail -10","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":"sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper\nsudo: a password is required","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":"Docker needs sudo+password. Let me verify the auth changes are correct by testing the logic directly:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Unit test the auth middleware logic","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"node - << 'EOF'\n// Simulate the auth middleware logic\nconst API_KEY = '94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c';\nprocess.env.API_KEY = API_KEY;\n\nconst { authentikMiddleware } = require('/volume2/docker/finance/finance-hub/backend/src/auth.js');\n\nfunction testReq(path, headers = {}) {\n const res = { status(code) { this.code = code; return this; }, json(body) { return body; } };\n const req = { path, headers };\n let passed = false;\n authentikMiddleware(req, res, () => { passed = true; });\n return { passed, code: res.code, user: req.user };\n}\n\n// Public path — no auth needed\nlet r = testReq('/api/health', {});\nconsole.assert(r.passed, 'health should be public');\nconsole.log('✓ /api/health is public');\n\n// Valid API key\nr = testReq('/api/payments', { authorization: `Bearer ${API_KEY}` });\nconsole.assert(r.passed, 'valid key should pass');\nconsole.assert(r.user.username === 'api-key', 'api user');\nconsole.log('✓ valid API key passes');\n\n// Wrong API key\nr = testReq('/api/payments', { authorization: 'Bearer wrongkey' });\nconsole.assert(!r.passed, 'wrong key should fail');\nconsole.assert(r.code === 401, '401 on bad key');\nconsole.log('✓ wrong API key returns 401');\n\n// No auth + no bypass + no authentik header\nprocess.env.DEV_BYPASS_AUTH = 'false';\nr = testReq('/api/payments', {});\nconsole.assert(!r.passed && r.code === 401, 'no creds → 401');\nconsole.log('✓ no credentials returns 401');\n\n// Upload endpoints no longer public\nr = testReq('/api/upload/csv', {});\nconsole.assert(!r.passed && r.code === 401, 'upload/csv requires auth');\nconsole.log('✓ /api/upload/csv now requires auth (was public, now fixed)');\n\n// Authentik header pass-through\nr = testReq('/api/payments', { 'x-authentik-username': 'lukastest', 'x-authentik-email': 'test@test.com' });\nconsole.assert(r.passed && r.user.username === 'lukastest', 'authentik header works');\nconsole.log('✓ Authentik X-authentik-username header works');\n\nconsole.log('\\nAll auth tests passed.');\nEOF","depth":26,"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":"✓ /api/health is public\n✓ valid API key passes\n✓ wrong API key returns 401\n✓ no credentials returns 401\n✓ /api/upload/csv now requires auth (was public, now fixed)\n✓ Authentik X-authentik-username header works\n\nAll auth tests passed.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"All auth cases pass. Now test the MCP spending_by_tag tool against the live backend (with DEV_BYPASS_AUTH still on):","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Test spending_by_tag MCP tool against live backend","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"cd /volume2/docker/finance/finance-hub/mcp && \\\n printf '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\",\"params\":{}}\\n{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/call\",\"params\":{\"name\":\"spending_by_tag\",\"arguments\":{\"dateFrom\":\"2026-05-01\",\"dateTo\":\"2026-05-09\"}}}\\n' | \\\n FINANCE_HUB_URL=http://localhost:3001 FINANCE_HUB_API_KEY=94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c \\\n timeout 8 node server.js 2>/dev/null | grep '\"id\":2' | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d['result']['content'][0]['text'][:500])\"","depth":26,"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":"{\n \"period\": {\n \"from\": \"2026-05-01\",\n \"to\": \"2026-05-09\"\n },\n \"totalTransactions\": 36,\n \"breakdown\": [\n {\n \"tag\": \"Bills\",\n \"total\": 117.9,\n \"count\": 6\n },\n {\n \"tag\": \"(untagged)\",\n \"total\": 1153.87,\n \"count\": 22\n }\n ]\n}","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MCP tools work correctly against real data. Let me write the Claude desktop config example and the","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".gitignore","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"for the mcp dir:","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":"claude_desktop_config.example.json","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"claude_desktop_config.example.json","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"14 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"{\n \"_comment\": \"Add this block to ~/.config/claude/claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json)\",\n \"mcpServers\": {\n \"finance-hub\": {\n \"command\": \"node\",\n \"args\": [\"/volume2/docker/finance/finance-hub/mcp/server.js\"],\n \"env\": {\n \"FINANCE_HUB_URL\": \"http://localhost:3001\",\n \"FINANCE_HUB_API_KEY\": \"94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c\"\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":".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":"2 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"node_modules/","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update Todos","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Fix auth.js: add API key support + remove upload endpoints from PUBLIC_PATHS","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update index.js: add CORS origin restriction via env var","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update .env and .env.example with API_KEY variable","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Build MCP server (stdio, Claude desktop compatible)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Test: restart backend, verify API key auth and MCP connection","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Now let me save relevant project context to memory:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"MEMORY.md","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"MEMORY.md","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":"MEMORY.md","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"MEMORY.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"4 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"# Memory Index\n\n- [project_finance_hub.md](project_finance_hub.md) — Finance Hub architecture, auth design, MCP server, API key setup","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":"project_finance_hub.md","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"project_finance_hub.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"35 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"---\nname: Finance Hub project state\ndescription: Architecture, auth design, API key, MCP server location and tools for the finance-hub project\ntype: project\n---\n\nFinance Hub is a personal finance tracker at `/volume2/docker/finance/finance-hub/`.\n\n**Running services** (as of 2026-05-09):\n- Backend: port 3001 (Express/Prisma, PostgreSQL)\n- Frontend: port 5175 (React/Vite)\n- Adminer: port 8092\n- Authentik: port 9100 (auth.lakylak.xyz, tag 2026.2.1)\n\n**Auth design:**\n- Production: NPM (Nginx Proxy Manager) + Authentik forward-auth outpost → injects `X-authentik-username` header\n- `DEV_BYPASS_AUTH=true` is currently set in `.env` — app runs without real auth\n- API key auth added: `Authorization: Bearer <API_KEY>` bypasses Authentik header check (used by MCP/scripts)\n- API_KEY in `.env`: `94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c`\n\n**Public endpoints** (no auth): `/api/health`, `/api/payments/ingest`\n\n**Security fix applied (2026-05-09):** Removed `/api/upload/csv` and `/api/upload/preview` from PUBLIC_PATHS — they were incorrectly public.\n\n**MCP server:** `/volume2/docker/finance/finance-hub/mcp/server.js`\n- Stdio transport, works with Claude desktop\n- Tools: list_transactions, spending_by_tag, get_transaction, list_tags, add_tag, remove_tag, health_check\n- Env: FINANCE_HUB_URL, FINANCE_HUB_API_KEY\n- Config example: `mcp/claude_desktop_config.example.json`\n\n**To enable real Authentik auth:** Set `DEV_BYPASS_AUTH=false` in `.env`, configure NPM proxy host for finance-hub with the Authentik NPM nginx snippet (see `/volume2/docker/finance/auth/README.md`).\n\n**Why:** Application had no production auth despite Authentik being available and running.\n**How to apply:** When asked about enabling auth or going to production, walk through NPM proxy + Authentik outpost steps from the README. API_KEY is already set for MCP.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Here's a full summary of what was done and the findings:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"What was built and fixed","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"What was built and fixed","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Security fixes","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Security fixes","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bug fixed:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/api/upload/csv","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"and","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/api/upload/preview","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"were in","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PUBLIC_PATHS","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— anyone on the network could upload files without authentication. Both are now protected. Only","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/api/health","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"and","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/api/payments/ingest","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"remain public.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CORS restriction added:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"index.js","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"now reads","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CORS_ORIGIN","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"from env. Set it to your frontend domain (e.g.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"https://finance.lakylak.xyz","depth":24,"on_screen":false,"role_description":"text"}]...
|
-1414998924977588280
|
-6500787940164139007
|
click
|
accessibility
|
NULL
|
Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧ Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧G) - 12 pending changes
12
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
mcp
scripts
.env
.env.example
M
.gitignore
M
docker-compose.yml
M
README.md
sms_export.json
payments-logger
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
docker-compose.yml, Editor Group 1
.env, Editor Group 1
.env.example, preview, Editor Group 1
report(1).csv, Editor Group 1
report(2).csv, Editor Group 1
sms_export.json, Editor Group 1
# ── Database ───────────────────────────────────────────────────────────────────
[ENV_SECRET]
# ── Notifier service ──────────────────────────────────────────────────────────
NOTIFIER_URL=[URL_WITH_CREDENTIALS]
# Secret key — generate with: openssl rand -base64 36
[ENV_SECRET]
# Public URL authentik is reachable at (used for redirects and the outpost)
AUTHENTIK_HOST=[URL_WITH_CREDENTIALS] version 2>/dev/null && node --version
Copy code to clipboard
OUT
Exit code 127
Bash
Verify public path configuration
IN
# Check if the upload endpoints are really public
grep -n 'PUBLIC_PATHS\|upload\|ingest' /volume2/docker/finance/finance-hub/backend/src/auth.js
Copy code to clipboard
OUT
<tool_use_error>Cancelled: parallel tool call Bash(npm view @modelcontextprotocol/sdk versi…) errored</tool_use_error>
Bash
Check node version and MCP SDK latest
IN
node --version 2>/dev/null && python3 -c "import urllib.request; import json; d=json.loads(urllib.request.urlopen('[URL_WITH_CREDENTIALS] "^1.29.0"
},
"engines": {
"node": ">=18"
}
}
Write
server.js
server.js
236 lines
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
const BASE_URL = (process.env.FINANCE_HUB_URL || '[URL_WITH_CREDENTIALS] '^1.29.0'}
Thinking
Thinking
Good. Now let me test the MCP server can at least start and call the health check:
Bash
Smoke test MCP server startup
IN
FINANCE_HUB_URL=http://localhost:3001 [ENV_SECRET] \
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | timeout 5 node server.js 2>/dev/null | head -3 || echo "NODE test (expected timeout on stdin wait)"
Copy code to clipboard
OUT
{"result":{"tools":[{"name":"list_transactions","description":"List finance transactions with optional filters. Returns paginated results including total amount for the filtered set.","inputSchema":{"type":"object","properties":{"page":{"type":"number","description":"Page number (default 1)"},"limit":{"type":"number","description":"Results per page, max 200 (default 50)"},"dateFrom":{"type":"string","description":"Start date YYYY-MM-DD (inclusive)"},"dateTo":{"type":"string","description":"End date YYYY-MM-DD (inclusive)"},"tag":{"type":"string","description":"Filter by tag name"},"recipient":{"type":"string","description":"Substring match on payee name"},"type":{"type":"string","description":"Transaction type: POS | ATM | WALLET"},"source":{"type":"string","description":"Import source: INGEST | UPLOAD"},"search":{"type":"string","description":"Full-text search across rawMessage and recipient"},"hideBalanceAlerts":{"type":"boolean","description":"Exclude balance-notification SMS (default false)"},"sortBy":{"type":"string","description":"Sort field: date | amount | recipient | createdAt"},"sortDir":{"type":"string","description":"asc or desc (default desc)"}}}},{"name":"spending_by_tag","description":"Aggregate spending totals by tag for a date range. Fetches up to 200 transactions and groups them. Good for monthly summaries.","inputSchema":{"type":"object","properties":{"dateFrom":{"type":"string","description":"Start date YYYY-MM-DD"},"dateTo":{"type":"string","description":"End date YYYY-MM-DD"}}}},{"name":"get_transaction","description":"Get a single transaction by its numeric ID.","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"number","description":"Transaction import ID"}}}},{"name":"list_tags","description":"List all available tags with their colors.","inputSchema":{"type":"object","properties":{}}},{"name":"add_tag","description":"Add a tag to a transaction. Creates the tag globally if it does not exist.","inputSchema":{"type":"object","required":["id","name"],"properties":{"id":{"type":"number","description":"Transaction ID"},"name":{"type":"string","description":"Tag name (e.g. \"Groceries\")"},"color":{"type":"string","description":"Hex color (e.g. \"#22c55e\"). Optional — auto-assigned if omitted."}}}},{"name":"remove_tag","description":"Remove a tag from a transaction.","inputSchema":{"type":"object","required":["id","tagId"],"properties":{"id":{"type":"number","description":"Transaction ID"},"tagId":{"type":"number","description":"Tag ID (from list_tags or the transaction object)"}}}},{"name":"health_check","description":"Check Finance Hub backend connectivity and database status.","inputSchema":{"type":"object","properties":{}}}]},"jsonrpc":"2.0","id":1}
Thinking
Thinking
MCP server responds correctly. Now test an actual tool call:
Bash
Test MCP health_check tool against live backend
IN
\
printf '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}\n{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"health_check","arguments":{}}}\n' | \
FINANCE_HUB_URL=http://localhost:3001 [ENV_SECRET] \
timeout 5 node server.js 2>/dev/null | tail -1 | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['result']['content'][0]['text'])"
Copy code to clipboard
OUT
{
"status": "ok",
"timestamp": "2026-05-09T16:19:09.977Z",
"storage": {
"type": "PostgreSQL",
"host": "db",
"database": "finance_hub"
}
}
Bash
Rebuild backend with API key auth changes
IN
# Test the API key auth directly against the backend (backend still has DEV_BYPASS_AUTH=true, need to restart first)
# First rebuild with the new code
cd /volume2/docker/finance/finance-hub && docker compose up -d --build backend 2>&1 | tail -8
Copy code to clipboard
OUT
time="2026-05-09T19:19:13+03:00" level=warning msg="/volume2/docker/finance/finance-hub/docker-compose.yml: `version` is obsolete"
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.45/containers/json?all=1&filters=%7B%22label%22%3A%7B%22com.docker.compose.config-hash%22%3Atrue%2C%22com.docker.compose.project%3Dfinance-hub%22%3Atrue%7D%7D": dial unix /var/run/docker.sock: connect: permission denied
Bash
Rebuild backend with sudo
IN
sudo docker compose -f /volume2/docker/finance/finance-hub/docker-compose.yml up -d --build backend 2>&1 | tail -10
Copy code to clipboard
OUT
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
sudo: a password is required
Thinking
Thinking
Docker needs sudo+password. Let me verify the auth changes are correct by testing the logic directly:
Bash
Unit test the auth middleware logic
IN
node - << 'EOF'
// Simulate the auth middleware logic
const [ENV_SECRET];
process.env.API_KEY = API_KEY;
const { authentikMiddleware } = require('/volume2/docker/finance/finance-hub/backend/src/auth.js');
function testReq(path, headers = {}) {
const res = { status(code) { this.code = code; return this; }, json(body) { return body; } };
const req = { path, headers };
let passed = false;
authentikMiddleware(req, res, () => { passed = true; });
return { passed, code: res.code, user: req.user };
}
// Public path — no auth needed
let r = testReq('/api/health', {});
console.assert(r.passed, 'health should be public');
console.log('✓ /api/health is public');
// Valid API key
r = testReq('/api/payments', { authorization: `Bearer ${API_KEY}` });
console.assert(r.passed, 'valid key should pass');
console.assert(r.user.username === 'api-key', 'api user');
console.log('✓ valid API key passes');
// Wrong API key
r = testReq('/api/payments', { authorization: 'Bearer wrongkey' });
console.assert(!r.passed, 'wrong key should fail');
console.assert(r.code === 401, '401 on bad key');
console.log('✓ wrong API key returns 401');
// No auth + no bypass + no authentik header
process.env.DEV_BYPASS_AUTH = 'false';
r = testReq('/api/payments', {});
console.assert(!r.passed && r.code === 401, 'no creds → 401');
console.log('✓ no credentials returns 401');
// Upload endpoints no longer public
r = testReq('/api/upload/csv', {});
console.assert(!r.passed && r.code === 401, 'upload/csv requires auth');
console.log('✓ /api/upload/csv now requires auth (was public, now fixed)');
// Authentik header pass-through
r = testReq('/api/payments', { 'x-authentik-username': 'lukastest', 'x-authentik-email': '[EMAIL]' });
console.assert(r.passed && r.user.username === 'lukastest', 'authentik header works');
console.log('✓ Authentik X-authentik-username header works');
console.log('\nAll auth tests passed.');
EOF
Copy code to clipboard
OUT
✓ /api/health is public
✓ valid API key passes
✓ wrong API key returns 401
✓ no credentials returns 401
✓ /api/upload/csv now requires auth (was public, now fixed)
✓ Authentik X-authentik-username header works
All auth tests passed.
All auth cases pass. Now test the MCP spending_by_tag tool against the live backend (with DEV_BYPASS_AUTH still on):
Bash
Test spending_by_tag MCP tool against live backend
IN
cd /volume2/docker/finance/finance-hub/mcp && \
printf '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}\n{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"spending_by_tag","arguments":{"dateFrom":"2026-05-01","dateTo":"2026-05-09"}}}\n' | \
FINANCE_HUB_URL=http://localhost:3001 [ENV_SECRET] \
timeout 8 node server.js 2>/dev/null | grep '"id":2' | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['result']['content'][0]['text'][:500])"
Copy code to clipboard
OUT
{
"period": {
"from": "2026-05-01",
"to": "2026-05-09"
},
"totalTransactions": 36,
"breakdown": [
{
"tag": "Bills",
"total": 117.9,
"count": 6
},
{
"tag": "(untagged)",
"total": 1153.87,
"count": 22
}
]
}
MCP tools work correctly against real data. Let me write the Claude desktop config example and the
.gitignore
for the mcp dir:
Write
claude_desktop_config.example.json
claude_desktop_config.example.json
14 lines
{
"_comment": "Add this block to ~/.config/claude/claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json)",
"mcpServers": {
"finance-hub": {
"command": "node",
"args": ["/volume2/docker/finance/finance-hub/mcp/server.js"],
"env": {
"FINANCE_HUB_URL": "http://localhost:3001",
"FINANCE_HUB_API_KEY": "94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c"
}
}
}
}
Write
.gitignore
.gitignore
2 lines
node_modules/
Update Todos
Fix auth.js: add API key support + remove upload endpoints from PUBLIC_PATHS
Update index.js: add CORS origin restriction via env var
Update .env and .env.example with API_KEY variable
Build MCP server (stdio, Claude desktop compatible)
Test: restart backend, verify API key auth and MCP connection
Now let me save relevant project context to memory:
Read
MEMORY.md
MEMORY.md
Write
MEMORY.md
MEMORY.md
4 lines
# Memory Index
- [project_finance_hub.md](project_finance_hub.md) — Finance Hub architecture, auth design, MCP server, API key setup
Write
project_finance_hub.md
project_finance_hub.md
35 lines
---
name: Finance Hub project state
description: Architecture, auth design, API key, MCP server location and tools for the finance-hub project
type: project
---
Finance Hub is a personal finance tracker at `/volume2/docker/finance/finance-hub/`.
**Running services** (as of 2026-05-09):
- Backend: port 3001 (Express/Prisma, PostgreSQL)
- Frontend: port 5175 (React/Vite)
- Adminer: port 8092
- Authentik: port 9100 (auth.lakylak.xyz, tag 2026.2.1)
**Auth design:**
- Production: NPM (Nginx Proxy Manager) + Authentik forward-auth outpost → injects `X-authentik-username` header
- `DEV_BYPASS_AUTH=true` is currently set in `.env` — app runs without real auth
- API key auth added: `Authorization: Bearer <API_KEY>` bypasses Authentik header check (used by MCP/scripts)
- API_KEY in `.env`: `94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c`
**Public endpoints** (no auth): `/api/health`, `/api/payments/ingest`
**Security fix applied (2026-05-09):** Removed `/api/upload/csv` and `/api/upload/preview` from PUBLIC_PATHS — they were incorrectly public.
**MCP server:** `/volume2/docker/finance/finance-hub/mcp/server.js`
- Stdio transport, works with Claude desktop
- Tools: list_transactions, spending_by_tag, get_transaction, list_tags, add_tag, remove_tag, health_check
- Env: FINANCE_HUB_URL, FINANCE_HUB_API_KEY
- Config example: `mcp/claude_desktop_config.example.json`
**To enable real Authentik auth:** Set `DEV_BYPASS_AUTH=false` in `.env`, configure NPM proxy host for finance-hub w...
|
14181
|
NULL
|
NULL
|
NULL
|
|
14186
|
629
|
40
|
2026-05-09T17:03:34.125040+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778346214125_m1.jpg...
|
iTerm2
|
-zsh
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
0413\u0418\u042f | Debit: 0.09 EUR",
0413\u0418\u042f | Debit: 0.09 EUR",
"date": "2026-05-04T00:00:00.000Z",
"type": null,
"card": null,
"recipient": "\u0415\u041b\u0415\u041a\u0422P\u041e\u0425\u041e\u041b\u0414\u041fP\u041e\u0414\u0410\u0416\u0411\u0418/\u0414\u0421\u041a\u0414\u0418\u0420\u0415\u041a\u0422/\u0415\u041b.\u0415\u041d\u0415\u0420\u0413\u0418\u042f",
"amount": 0.09,
"currency": "EUR",
"balance": null,
"source": "UPLOAD",
"debitBgn": 0.09,
"creditBgn": null,
"transactionType": "\u041a\u041e\u041c\u0423\u041d\u0410\u041b\u041d\u0418 \u0423\u0421\u041b\u0423\u0413\u0418",
"payerAccount": "[IBAN]",
"autoTags": [
"Bills"
]
},
{
"rawMessage": "Date: 04.05.2026 | Type: \u041a\u041e\u041c\u0423\u041d\u0410\u041b\u041d\u0418 \u0423\u0421\u041b\u0423\u0413\u0418 | Payee: \u04210\u0424\u0418\u0419\u0421\u041a\u0410 \u0412\u041e\u0414\u0410 \u0414\u0421\u041a \u0414\u0418\u0420\u0415\u041a\u0422 | Debit: 29.54 EUR",
"date": "2026-05-04T00:00:00.000Z",
"type": null,
"card": null,
"recipient": "\u04210\u0424\u0418\u0419\u0421\u041a\u0410 \u0412\u041e\u0414\u0410 \u0414\u0421\u041a \u0414\u0418\u0420\u0415\u041a\u0422",
"amount": 29.54,
"currency": "EUR",
"balance": null,
"source": "UPLOAD",
"debitBgn": 29.54,
"creditBgn": null,
"transactionType": "\u041a\u041e\u041c\u0423\u041d\u0410\u041b\u041d\u0418 \u0423\u0421\u041b\u0423\u0413\u0418",
"payerAccount": "[IBAN]",
"autoTags": [
"Bills"
]
}
],
"total": 10,
"skipped": 0,
"errors": []
}
]
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/Downloads $ clear
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/Downloads $ curl -s -o /dev/null -w "%{http_code}" [URL_WITH_CREDENTIALS] ~/Downloads $ curl -s -H "Authorization: [AUTH_TOKEN]" \
[URL_WITH_CREDENTIALS] ~/Downloads $ curl -s -H "Authorization: [AUTH_TOKEN]" \
"https://finance-hub.lakylak.xyz/api/payments?limit=1"
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>openresty</center>
</body>
</html>
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/Downloads $ curl -s https://finance-mcp.lakylak.xyz/.well-known/oauth-authorization-server | python3 -m json.tool
DOCKER
Close Tab
DEV (-zsh)
Close Tab
APP (-zsh)
Close Tab
-zsh
Close Tab
screenpipe"
Close Tab
-zsh
Close Tab
ssh
Close Tab
⌥⌘1
-zsh...
|
[{"role":"AXTextArea","text [{"role":"AXTextArea","text":"0413\\u0418\\u042f | Debit: 0.09 EUR\",\n \"date\": \"2026-05-04T00:00:00.000Z\",\n \"type\": null,\n \"card\": null,\n \"recipient\": \"\\u0415\\u041b\\u0415\\u041a\\u0422P\\u041e\\u0425\\u041e\\u041b\\u0414\\u041fP\\u041e\\u0414\\u0410\\u0416\\u0411\\u0418/\\u0414\\u0421\\u041a\\u0414\\u0418\\u0420\\u0415\\u041a\\u0422/\\u0415\\u041b.\\u0415\\u041d\\u0415\\u0420\\u0413\\u0418\\u042f\",\n \"amount\": 0.09,\n \"currency\": \"EUR\",\n \"balance\": null,\n \"source\": \"UPLOAD\",\n \"debitBgn\": 0.09,\n \"creditBgn\": null,\n \"transactionType\": \"\\u041a\\u041e\\u041c\\u0423\\u041d\\u0410\\u041b\\u041d\\u0418 \\u0423\\u0421\\u041b\\u0423\\u0413\\u0418\",\n \"payerAccount\": \"BG15STSA93000004594031\",\n \"autoTags\": [\n \"Bills\"\n ]\n },\n {\n \"rawMessage\": \"Date: 04.05.2026 | Type: \\u041a\\u041e\\u041c\\u0423\\u041d\\u0410\\u041b\\u041d\\u0418 \\u0423\\u0421\\u041b\\u0423\\u0413\\u0418 | Payee: \\u04210\\u0424\\u0418\\u0419\\u0421\\u041a\\u0410 \\u0412\\u041e\\u0414\\u0410 \\u0414\\u0421\\u041a \\u0414\\u0418\\u0420\\u0415\\u041a\\u0422 | Debit: 29.54 EUR\",\n \"date\": \"2026-05-04T00:00:00.000Z\",\n \"type\": null,\n \"card\": null,\n \"recipient\": \"\\u04210\\u0424\\u0418\\u0419\\u0421\\u041a\\u0410 \\u0412\\u041e\\u0414\\u0410 \\u0414\\u0421\\u041a \\u0414\\u0418\\u0420\\u0415\\u041a\\u0422\",\n \"amount\": 29.54,\n \"currency\": \"EUR\",\n \"balance\": null,\n \"source\": \"UPLOAD\",\n \"debitBgn\": 29.54,\n \"creditBgn\": null,\n \"transactionType\": \"\\u041a\\u041e\\u041c\\u0423\\u041d\\u0410\\u041b\\u041d\\u0418 \\u0423\\u0421\\u041b\\u0423\\u0413\\u0418\",\n \"payerAccount\": \"BG03STSA93000045940400\",\n \"autoTags\": [\n \"Bills\"\n ]\n }\n ],\n \"total\": 10,\n \"skipped\": 0,\n \"errors\": []\n }\n]\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/Downloads $ clear\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/Downloads $ curl -s -o /dev/null -w \"%{http_code}\" https://finance-hub.lakylak.xyz/api/payments\n302% \nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/Downloads $ curl -s https://finance-hub.lakylak.xyz/api/health\n{\"status\":\"ok\",\"timestamp\":\"2026-05-09T16:43:04.504Z\",\"storage\":{\"type\":\"PostgreSQL\",\"host\":\"db\",\"database\":\"finance_hub\"}}% lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/Downloads $ curl -s -H \"Authorization: Bearer 94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c\" \\\n https://finance-hub.lakylak.xyz/api/payments?limit=1 | head -50\nzsh: no matches found: https://finance-hub.lakylak.xyz/api/payments?limit=1\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/Downloads $ curl -s -H \"Authorization: Bearer 94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c\" \\\n \"https://finance-hub.lakylak.xyz/api/payments?limit=1\"\n\n<html>\n<head><title>302 Found</title></head>\n<body>\n<center><h1>302 Found</h1></center>\n<hr><center>openresty</center>\n</body>\n</html>\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/Downloads $ curl -s https://finance-mcp.lakylak.xyz/.well-known/oauth-authorization-server | python3 -m json.tool","depth":4,"on_screen":true,"value":"0413\\u0418\\u042f | Debit: 0.09 EUR\",\n \"date\": \"2026-05-04T00:00:00.000Z\",\n \"type\": null,\n \"card\": null,\n \"recipient\": \"\\u0415\\u041b\\u0415\\u041a\\u0422P\\u041e\\u0425\\u041e\\u041b\\u0414\\u041fP\\u041e\\u0414\\u0410\\u0416\\u0411\\u0418/\\u0414\\u0421\\u041a\\u0414\\u0418\\u0420\\u0415\\u041a\\u0422/\\u0415\\u041b.\\u0415\\u041d\\u0415\\u0420\\u0413\\u0418\\u042f\",\n \"amount\": 0.09,\n \"currency\": \"EUR\",\n \"balance\": null,\n \"source\": \"UPLOAD\",\n \"debitBgn\": 0.09,\n \"creditBgn\": null,\n \"transactionType\": \"\\u041a\\u041e\\u041c\\u0423\\u041d\\u0410\\u041b\\u041d\\u0418 \\u0423\\u0421\\u041b\\u0423\\u0413\\u0418\",\n \"payerAccount\": \"BG15STSA93000004594031\",\n \"autoTags\": [\n \"Bills\"\n ]\n },\n {\n \"rawMessage\": \"Date: 04.05.2026 | Type: \\u041a\\u041e\\u041c\\u0423\\u041d\\u0410\\u041b\\u041d\\u0418 \\u0423\\u0421\\u041b\\u0423\\u0413\\u0418 | Payee: \\u04210\\u0424\\u0418\\u0419\\u0421\\u041a\\u0410 \\u0412\\u041e\\u0414\\u0410 \\u0414\\u0421\\u041a \\u0414\\u0418\\u0420\\u0415\\u041a\\u0422 | Debit: 29.54 EUR\",\n \"date\": \"2026-05-04T00:00:00.000Z\",\n \"type\": null,\n \"card\": null,\n \"recipient\": \"\\u04210\\u0424\\u0418\\u0419\\u0421\\u041a\\u0410 \\u0412\\u041e\\u0414\\u0410 \\u0414\\u0421\\u041a \\u0414\\u0418\\u0420\\u0415\\u041a\\u0422\",\n \"amount\": 29.54,\n \"currency\": \"EUR\",\n \"balance\": null,\n \"source\": \"UPLOAD\",\n \"debitBgn\": 29.54,\n \"creditBgn\": null,\n \"transactionType\": \"\\u041a\\u041e\\u041c\\u0423\\u041d\\u0410\\u041b\\u041d\\u0418 \\u0423\\u0421\\u041b\\u0423\\u0413\\u0418\",\n \"payerAccount\": \"BG03STSA93000045940400\",\n \"autoTags\": [\n \"Bills\"\n ]\n }\n ],\n \"total\": 10,\n \"skipped\": 0,\n \"errors\": []\n }\n]\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/Downloads $ clear\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/Downloads $ curl -s -o /dev/null -w \"%{http_code}\" https://finance-hub.lakylak.xyz/api/payments\n302% \nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/Downloads $ curl -s https://finance-hub.lakylak.xyz/api/health\n{\"status\":\"ok\",\"timestamp\":\"2026-05-09T16:43:04.504Z\",\"storage\":{\"type\":\"PostgreSQL\",\"host\":\"db\",\"database\":\"finance_hub\"}}% lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/Downloads $ curl -s -H \"Authorization: Bearer 94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c\" \\\n https://finance-hub.lakylak.xyz/api/payments?limit=1 | head -50\nzsh: no matches found: https://finance-hub.lakylak.xyz/api/payments?limit=1\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/Downloads $ curl -s -H \"Authorization: Bearer 94bb2917b9a1b9dcbaec49e7009c2a6b222fc310d32f530aa07e411e8d4a058c\" \\\n \"https://finance-hub.lakylak.xyz/api/payments?limit=1\"\n\n<html>\n<head><title>302 Found</title></head>\n<body>\n<center><h1>302 Found</h1></center>\n<hr><center>openresty</center>\n</body>\n</html>\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/Downloads $ curl -s https://finance-mcp.lakylak.xyz/.well-known/oauth-authorization-server | python3 -m json.tool","is_focused":true},{"role":"AXRadioButton","text":"DOCKER","depth":2,"bounds":{"left":0.0,"top":0.05888889,"width":0.140625,"height":0.026666667},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.0034722222,"top":0.06333333,"width":0.011111111,"height":0.017777778},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"DEV (-zsh)","depth":2,"bounds":{"left":0.13993056,"top":0.05888889,"width":0.140625,"height":0.026666667},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.14409722,"top":0.06333333,"width":0.011111111,"height":0.017777778},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"APP (-zsh)","depth":2,"bounds":{"left":0.28055555,"top":0.05888889,"width":0.140625,"height":0.026666667},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.2847222,"top":0.06333333,"width":0.011111111,"height":0.017777778},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.42118055,"top":0.05888889,"width":0.140625,"height":0.026666667},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.4253472,"top":0.06333333,"width":0.011111111,"height":0.017777778},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"screenpipe\"","depth":2,"bounds":{"left":0.56180555,"top":0.05888889,"width":0.14027777,"height":0.026666667},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.5659722,"top":0.06333333,"width":0.011111111,"height":0.017777778},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.70208335,"top":0.05888889,"width":0.14027777,"height":0.026666667},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.70625,"top":0.06333333,"width":0.011111111,"height":0.017777778},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"ssh","depth":2,"bounds":{"left":0.8423611,"top":0.05888889,"width":0.14027777,"height":0.026666667},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.84652776,"top":0.06333333,"width":0.011111111,"height":0.017777778},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"⌥⌘1","depth":1,"bounds":{"left":0.95416665,"top":0.032222223,"width":0.03888889,"height":0.018888889},"on_screen":true,"automation_id":"_NS:8","role_description":"text"},{"role":"AXStaticText","text":"-zsh","depth":1,"bounds":{"left":0.4875,"top":0.033333335,"width":0.022916667,"height":0.017777778},"on_screen":true,"role_description":"text"}]...
|
-6406098145192016923
|
912713866539698629
|
visual_change
|
accessibility
|
NULL
|
0413\u0418\u042f | Debit: 0.09 EUR",
0413\u0418\u042f | Debit: 0.09 EUR",
"date": "2026-05-04T00:00:00.000Z",
"type": null,
"card": null,
"recipient": "\u0415\u041b\u0415\u041a\u0422P\u041e\u0425\u041e\u041b\u0414\u041fP\u041e\u0414\u0410\u0416\u0411\u0418/\u0414\u0421\u041a\u0414\u0418\u0420\u0415\u041a\u0422/\u0415\u041b.\u0415\u041d\u0415\u0420\u0413\u0418\u042f",
"amount": 0.09,
"currency": "EUR",
"balance": null,
"source": "UPLOAD",
"debitBgn": 0.09,
"creditBgn": null,
"transactionType": "\u041a\u041e\u041c\u0423\u041d\u0410\u041b\u041d\u0418 \u0423\u0421\u041b\u0423\u0413\u0418",
"payerAccount": "[IBAN]",
"autoTags": [
"Bills"
]
},
{
"rawMessage": "Date: 04.05.2026 | Type: \u041a\u041e\u041c\u0423\u041d\u0410\u041b\u041d\u0418 \u0423\u0421\u041b\u0423\u0413\u0418 | Payee: \u04210\u0424\u0418\u0419\u0421\u041a\u0410 \u0412\u041e\u0414\u0410 \u0414\u0421\u041a \u0414\u0418\u0420\u0415\u041a\u0422 | Debit: 29.54 EUR",
"date": "2026-05-04T00:00:00.000Z",
"type": null,
"card": null,
"recipient": "\u04210\u0424\u0418\u0419\u0421\u041a\u0410 \u0412\u041e\u0414\u0410 \u0414\u0421\u041a \u0414\u0418\u0420\u0415\u041a\u0422",
"amount": 29.54,
"currency": "EUR",
"balance": null,
"source": "UPLOAD",
"debitBgn": 29.54,
"creditBgn": null,
"transactionType": "\u041a\u041e\u041c\u0423\u041d\u0410\u041b\u041d\u0418 \u0423\u0421\u041b\u0423\u0413\u0418",
"payerAccount": "[IBAN]",
"autoTags": [
"Bills"
]
}
],
"total": 10,
"skipped": 0,
"errors": []
}
]
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/Downloads $ clear
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/Downloads $ curl -s -o /dev/null -w "%{http_code}" [URL_WITH_CREDENTIALS] ~/Downloads $ curl -s -H "Authorization: [AUTH_TOKEN]" \
[URL_WITH_CREDENTIALS] ~/Downloads $ curl -s -H "Authorization: [AUTH_TOKEN]" \
"https://finance-hub.lakylak.xyz/api/payments?limit=1"
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>openresty</center>
</body>
</html>
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/Downloads $ curl -s https://finance-mcp.lakylak.xyz/.well-known/oauth-authorization-server | python3 -m json.tool
DOCKER
Close Tab
DEV (-zsh)
Close Tab
APP (-zsh)
Close Tab
-zsh
Close Tab
screenpipe"
Close Tab
-zsh
Close Tab
ssh
Close Tab
⌥⌘1
-zsh...
|
14185
|
NULL
|
NULL
|
NULL
|
|
14482
|
643
|
40
|
2026-05-09T18:00:49.185931+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778349649185_m1.jpg...
|
iTerm2
|
NULL
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
CodeFileEditSelectionViewGoRunTerminalWindow Help→ CodeFileEditSelectionViewGoRunTerminalWindow Help→nas.lakylak.xyz/desktop/?os=ugospro#/Nginx Proxy Manager@Screenpipe - ArchiveSQLite Web: archive.dbSQLite Web: db.sqlitescreenpipe/.claude/skills at main - screenpipe/screenpDXP4800PLUS-B5F8AFFiNE - All In One KnowledgeOSAll docs • AFFiNEPayments LoggerM Your old PC can run Windows 11 in a VM, but not on baLocation LoggerFinance HubFinance HubSelect: transactions - db - AdminerClaude Code | Claude Platform* April 2026 spending by category - Claudelakylak/finance-hub - finance-hub - Gitea: Git with a c• Applications - Admin - authentik+ New TabFilesControl PanelPRIIStorageApp Center/logsLogsSupportQ Search|Connection & AccessUser ManagementFile ServiceW DeviceConnectionDomain/LDAP• TerminalGeneral|• Hardware & PowerTime & Language- NetworkSecurityE Indexing ServiceService• About‹ $0lallLA100% C8Sat 9 May 21:00:49CPU RAM1 5.1KвM=E: Control Panel?TelnetSSHEnablePort 23|Advanced settings• EnablePort22Shut down automatically3h later2026-05-09 21:18 will automatically shut downAdvanced settingsFunction descriptionyaswvord fir tie logi accoum ange nabie aute ok eo enhanice sysfeum secuitis recomended to sel a strongApply...
|
NULL
|
-9057840463383994369
|
NULL
|
visual_change
|
ocr
|
NULL
|
CodeFileEditSelectionViewGoRunTerminalWindow Help→ CodeFileEditSelectionViewGoRunTerminalWindow Help→nas.lakylak.xyz/desktop/?os=ugospro#/Nginx Proxy Manager@Screenpipe - ArchiveSQLite Web: archive.dbSQLite Web: db.sqlitescreenpipe/.claude/skills at main - screenpipe/screenpDXP4800PLUS-B5F8AFFiNE - All In One KnowledgeOSAll docs • AFFiNEPayments LoggerM Your old PC can run Windows 11 in a VM, but not on baLocation LoggerFinance HubFinance HubSelect: transactions - db - AdminerClaude Code | Claude Platform* April 2026 spending by category - Claudelakylak/finance-hub - finance-hub - Gitea: Git with a c• Applications - Admin - authentik+ New TabFilesControl PanelPRIIStorageApp Center/logsLogsSupportQ Search|Connection & AccessUser ManagementFile ServiceW DeviceConnectionDomain/LDAP• TerminalGeneral|• Hardware & PowerTime & Language- NetworkSecurityE Indexing ServiceService• About‹ $0lallLA100% C8Sat 9 May 21:00:49CPU RAM1 5.1KвM=E: Control Panel?TelnetSSHEnablePort 23|Advanced settings• EnablePort22Shut down automatically3h later2026-05-09 21:18 will automatically shut downAdvanced settingsFunction descriptionyaswvord fir tie logi accoum ange nabie aute ok eo enhanice sysfeum secuitis recomended to sel a strongApply...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
15038
|
673
|
40
|
2026-05-11T06:10:38.588900+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778479838588_m2.jpg...
|
PhpStorm
|
faVsco.js – RateLimitException.php
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Exceptions;
use Throwable;
class RateLimitException extends LogicException
{
public function __construct(
string $message = '',
private readonly int $retryAfter = 1,
?Throwable $previous = null,
) {
parent::__construct($message, 0, $previous);
}
public function getRetryAfter(): int
{
return max($this->retryAfter, 1);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20725-handle-HS-search-rate-limit, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09541223,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20725-handle-HS-search-rate-limit","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Exceptions;\n\nuse Throwable;\n\nclass RateLimitException extends LogicException\n{\n public function __construct(\n string $message = '',\n private readonly int $retryAfter = 1,\n ?Throwable $previous = null,\n ) {\n parent::__construct($message, 0, $previous);\n }\n\n public function getRetryAfter(): int\n {\n return max($this->retryAfter, 1);\n }\n}","depth":4,"bounds":{"left":0.11968085,"top":0.17158818,"width":0.2912234,"height":0.8076616},"on_screen":true,"lines":[{"char_start":7,"char_count":25,"bounds":{"left":0.11968085,"top":0.0,"width":0.06216755,"height":0.014365523}},{"char_start":33,"char_count":30,"bounds":{"left":0.11968085,"top":0.0,"width":0.07513298,"height":0.014365523}},{"char_start":64,"char_count":15,"bounds":{"left":0.11968085,"top":0.0,"width":0.036236703,"height":0.014365523}},{"char_start":80,"char_count":48,"bounds":{"left":0.11968085,"top":0.030327214,"width":0.12167553,"height":0.014365523}},{"char_start":128,"char_count":2,"bounds":{"left":0.11968085,"top":0.047885075,"width":0.0026595744,"height":0.014365523}},{"char_start":130,"char_count":33,"bounds":{"left":0.11968085,"top":0.065442935,"width":0.08277926,"height":0.014365523}},{"char_start":163,"char_count":30,"bounds":{"left":0.11968085,"top":0.0830008,"width":0.07513298,"height":0.014365523}},{"char_start":193,"char_count":46,"bounds":{"left":0.11968085,"top":0.10055866,"width":0.11635638,"height":0.014365523}},{"char_start":239,"char_count":37,"bounds":{"left":0.11968085,"top":0.11811652,"width":0.0930851,"height":0.014365523}},{"char_start":276,"char_count":8,"bounds":{"left":0.11968085,"top":0.13567439,"width":0.017952127,"height":0.014365523}},{"char_start":284,"char_count":53,"bounds":{"left":0.13763298,"top":0.13567439,"width":0.0026595744,"height":0.014365523}},{"char_start":337,"char_count":6,"bounds":{"left":0.13763298,"top":0.13567439,"width":0.010305851,"height":0.014365523}},{"char_start":344,"char_count":41,"bounds":{"left":0.11968085,"top":0.18834797,"width":0.10372341,"height":0.014365523}},{"char_start":385,"char_count":6,"bounds":{"left":0.22340426,"top":0.18834797,"width":0.0026595744,"height":0.014365523}},{"char_start":391,"char_count":42,"bounds":{"left":0.22340426,"top":0.18834797,"width":0.0026595744,"height":0.014365523}},{"char_start":433,"char_count":6,"bounds":{"left":0.22340426,"top":0.18834797,"width":0.012965426,"height":0.014365523}},{"char_start":439,"char_count":1,"bounds":{"left":0.11968085,"top":0.20590582,"width":0.0026595744,"height":0.014365523}}],"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Exceptions;\n\nuse Throwable;\n\nclass RateLimitException extends LogicException\n{\n public function __construct(\n string $message = '',\n private readonly int $retryAfter = 1,\n ?Throwable $previous = null,\n ) {\n parent::__construct($message, 0, $previous);\n }\n\n public function getRetryAfter(): int\n {\n return max($this->retryAfter, 1);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"19","depth":4,"bounds":{"left":0.6296542,"top":0.10055866,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6409575,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.64827126,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","depth":4,"bounds":{"left":0.43018618,"top":0.09736632,"width":0.56981385,"height":0.8818835},"on_screen":true,"value":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1435732321381728951
|
-2364366445847917750
|
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
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Exceptions;
use Throwable;
class RateLimitException extends LogicException
{
public function __construct(
string $message = '',
private readonly int $retryAfter = 1,
?Throwable $previous = null,
) {
parent::__construct($message, 0, $previous);
}
public function getRetryAfter(): int
{
return max($this->retryAfter, 1);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
15036
|
NULL
|
NULL
|
NULL
|
|
15039
|
672
|
40
|
2026-05-11T06:10:43.479042+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778479843479_m1.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelplabl| Daily - Platform • in 35 mA100% C47 8• Mon 11 May 9:10:43DEV (-zsh)• жз181DOCKERO ₴1DEV (-zsh)182APP (-zsh)* JY-20725-handle-HS-search-rate-limitmasterJY-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-UPaJY-18909-automated-reports-ask-jiminnyJY-20692-fix-integration-app-[API_KEY]@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ l-zsh-zsh885screenpipe"O 86DEV...
|
NULL
|
-2846866427046624222
|
NULL
|
click
|
ocr
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelplabl| Daily - Platform • in 35 mA100% C47 8• Mon 11 May 9:10:43DEV (-zsh)• жз181DOCKERO ₴1DEV (-zsh)182APP (-zsh)* JY-20725-handle-HS-search-rate-limitmasterJY-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-UPaJY-18909-automated-reports-ask-jiminnyJY-20692-fix-integration-app-[API_KEY]@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ l-zsh-zsh885screenpipe"O 86DEV...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
15382
|
687
|
40
|
2026-05-11T06:47:16.070018+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778482036070_m2.jpg...
|
PhpStorm
|
faVsco.js – custom.log
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
rireroxcalMistorbookmarksrTavsco.sProletey© Hubspo rireroxcalMistorbookmarksrTavsco.sProletey© HubspotWebhoo© HubspotSyncStrategyBase.phpCachedcrmservicebecorator.onp© ProspectCache.phpv D Pagination© HubspotPaginatC Paginationcontic© MatchActivityCrmData.php© CrmActivityService.phg(C) Paginationstate.•_ Prospectsearchstr> 0 Redisclass Cllent extends Baseclient 1mpLements Hubspotclientintertace-|A2 A65 X1X1~v D ServiceTraits# Opportunitysync866# SyncermEntitiesTSyncFieldstrait.T Writecrmtrait.p869•DUts•Weonook© BatchSyncCollector 872C) BatchSvncRedisSerl• Client.ohoC) ClosedDealStadesSG DealFieldsService.p© DecorateActivity.ph© FieldDefinitions.phpC) SieldTvneConverte(0) HubsnotClientinter(C) HubsnotTokenMan© PayloadBuilder.phpG DomotoCrmOhiontl© ResponseNormalizec) service.ono© SyncFieldAction.ph© SyncRelatedActivit© WebhookSyncBatcl• Ca IntegrationApp› Accessors•D ApI• contio> MDTO•D Filtersaobs• ProspectSearchStr.895• ServiceTraitsC) Dataclient.ohoC) DecorateActivitv.oh897 GC LocalSearch.nhn© LocalSearchinterfa( 899© RemoteSearch.php© Service.phpv Ml isteners© ConvertLeadActivite Duraol aokunGachalM Motadata• M Miarationoubuc tunction 1sunauthorizedzxcention Excention sel: 000lpllessage - surtocowertee-cgetnessageo)rneturn stn contains Smessage.sul-contaensplllessage'401 unauthorized') ||'http 401') |1str_contains($message,'status code 401') ||(preg_match( pattern: '/\b401\b/', Smessage) && str_contains($message, 'unauthorized'));* Vacloares und rerreshes une access coken it needed berore Ard requests.* Inas ensures cone-runnine processes con t tull aue to coken expzraczon.* dchrows soczalaccountlokenLnval1dexceptionpublic function ensureValidToken(: void1t sthis->oauthaccount === nulu *Snewloken = sthis->tokenmanagen->ensureval1dToken(sthis->oauthAccount):1+ Snewlioken == nulz <sthis->accesslloken = Snewtioken:public function getConfigonotunn Sthic-sconfia.II returns only active (archived=false)9 usagespublic function getOwners: arrayreturn Sthis->getNewInstance->crm->ownersO->getallO:• aparam b00l Sarchived• dreturn arrau<owner>— 31IIII 140 lDally - Platrorm • now100% L2. Mon 11 May 9:47:15=custom.log ^A SF (jiminny@localhost]4 HS_local [jiminny@localhost]Cascade# console [PKob.# console leu)# console [slAGiNG)[2026-05-07 14:21:15] local.INF0: [Hubspot] DEBUG Getting headers {MMI9AY"neaders".?Hubspot Rate Limit Rej caten (eanecaea tas sextentan sexcepten) .)+0 .."Uace":L"Inu,or May 2020 14.21.15 6Ml"Jncatch"Transter-Encod1nq":"chunked")."Connection":"keep-alive"\Sentry:: captureException($exception);Sresponse = sthis→>response→>errorinternalError selt::MESSAGE GENERALEXCEPTIONSEARCHING="CF-Ray":L"9t80debödb60dcsa-S0F"J,RateLimicexcepcion excepczon excends excepcion = so it talls through to the last catch"Strict-Transport-Secur1ty":"max-aqe=31536008* 1ncLudeSubDomains: preload")n• Reports to Sentry as a 500 internal error (noisy!)accent-encodino"• Returns errorInternalError to the client (extension shows "something went wrona")"access-control-allow-credentials": ["false"]."server-timing": ["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",• The user has no idea this is transientThis is the wrong outcome for a transient 429. There's no retry, no backoff, no useful UX.Contirmed callers"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],"So+-Cookie"." c+hm-Stlirtd0aXVr.kSandas6hzVVKhzTn0BidvMaheCtm0V-1778163675-1.0.1CrmController.php:84Sresponse = ScrmService->find(Sname, Sscopes):07-May-26 14:51:15 GMT; domain=.hubapi.com; Http0nly; Secure; SameSite=None"],"Report-To":["{"endpoints\":[{* Bul lhornSearchCommand (CLI debug only). So yes - fand() is essenttally controller-only. It is a synchronous request driven by user typing in the Chrome"unl".httns:la.nel.cloudflane.com./renon+W/v42c=NVA1cVTPQfVm32anS0#xVF/sd2RNWhat should hannen on rate limit\"group)":\"cf-nel\","max_age\":604800}"],"NEL":["{\"success_fraction\":0.01,"report to":|"cf-nel\"."max age":604800}"]"Server": ["cloudflare"]}} {This is a cunchronous HTTD reauest — we canlt releace-and-retrv like a ich Ontions ordered hv what I'd recommend.(a) Translate RateLimitException → HTTP 429 with Retrv-After header. This is the standard wav.D php} catch (RateLimitException $e) {return Sthis->response->setStatusCode(429)"correlation_ 1d":"95256555-ec98-4541-b9za-adta/Sboyeab",»ertrortoomanynequessl ern search race-tamared, predse reury shorcty.e"trace_10":C/AD8565-905t-4604-9405-0e5b551e5545"The frontend then shows a friendly "too many searches, retry in N seconds" instead of a generic error. No Sentry noise.(b) Inside find(), retry once with a short bounded sleep() (similar to searchCallByRecordingURLToken). HubSpot's SECONDLY policy has retry_after = 1 . Asinale 1sln-reauest retry.wouldlahsorh.the.most.common.case//secondlvlhurst Can.retries.at=a.svnchronousHTiTD reauest.shouldnlfhlock 10s/for TEN_SECONDI( Dunit cachofalures, (achesitreaber wit T. 0 il o ech an exception, butit does cache sucestil empy arcys. The 8009 eacthias et fandlresults actually helps absorb pressure under typina/repeat searches — that's good, leave it.Recommendation: (a) + (b) combined. Catch RateLimitException inside find(), retry once after min(SretryAfter, 1) s, and if it still fails, let it bubble: controllermaps it to HTTP 429 with Retrv-After7. The Syictind cleen(1) Retrv in searchcall cForPeriodBvPade cearchcal BvRecordinauRLTokenCurrent code• Service.php:1584-15993 catch (Fycention Ceycention)Sthis->logger→>info('(HubSpot) Search calls for period failed'. [...J):OK lets make it extremely simple. Only consider eclient- phpffL220-229 for CHubspotPaginationservice.php#fL162-198 lwill remove it from finPo. 4 spac...
|
NULL
|
-4729343904239792971
|
NULL
|
click
|
ocr
|
NULL
|
rireroxcalMistorbookmarksrTavsco.sProletey© Hubspo rireroxcalMistorbookmarksrTavsco.sProletey© HubspotWebhoo© HubspotSyncStrategyBase.phpCachedcrmservicebecorator.onp© ProspectCache.phpv D Pagination© HubspotPaginatC Paginationcontic© MatchActivityCrmData.php© CrmActivityService.phg(C) Paginationstate.•_ Prospectsearchstr> 0 Redisclass Cllent extends Baseclient 1mpLements Hubspotclientintertace-|A2 A65 X1X1~v D ServiceTraits# Opportunitysync866# SyncermEntitiesTSyncFieldstrait.T Writecrmtrait.p869•DUts•Weonook© BatchSyncCollector 872C) BatchSvncRedisSerl• Client.ohoC) ClosedDealStadesSG DealFieldsService.p© DecorateActivity.ph© FieldDefinitions.phpC) SieldTvneConverte(0) HubsnotClientinter(C) HubsnotTokenMan© PayloadBuilder.phpG DomotoCrmOhiontl© ResponseNormalizec) service.ono© SyncFieldAction.ph© SyncRelatedActivit© WebhookSyncBatcl• Ca IntegrationApp› Accessors•D ApI• contio> MDTO•D Filtersaobs• ProspectSearchStr.895• ServiceTraitsC) Dataclient.ohoC) DecorateActivitv.oh897 GC LocalSearch.nhn© LocalSearchinterfa( 899© RemoteSearch.php© Service.phpv Ml isteners© ConvertLeadActivite Duraol aokunGachalM Motadata• M Miarationoubuc tunction 1sunauthorizedzxcention Excention sel: 000lpllessage - surtocowertee-cgetnessageo)rneturn stn contains Smessage.sul-contaensplllessage'401 unauthorized') ||'http 401') |1str_contains($message,'status code 401') ||(preg_match( pattern: '/\b401\b/', Smessage) && str_contains($message, 'unauthorized'));* Vacloares und rerreshes une access coken it needed berore Ard requests.* Inas ensures cone-runnine processes con t tull aue to coken expzraczon.* dchrows soczalaccountlokenLnval1dexceptionpublic function ensureValidToken(: void1t sthis->oauthaccount === nulu *Snewloken = sthis->tokenmanagen->ensureval1dToken(sthis->oauthAccount):1+ Snewlioken == nulz <sthis->accesslloken = Snewtioken:public function getConfigonotunn Sthic-sconfia.II returns only active (archived=false)9 usagespublic function getOwners: arrayreturn Sthis->getNewInstance->crm->ownersO->getallO:• aparam b00l Sarchived• dreturn arrau<owner>— 31IIII 140 lDally - Platrorm • now100% L2. Mon 11 May 9:47:15=custom.log ^A SF (jiminny@localhost]4 HS_local [jiminny@localhost]Cascade# console [PKob.# console leu)# console [slAGiNG)[2026-05-07 14:21:15] local.INF0: [Hubspot] DEBUG Getting headers {MMI9AY"neaders".?Hubspot Rate Limit Rej caten (eanecaea tas sextentan sexcepten) .)+0 .."Uace":L"Inu,or May 2020 14.21.15 6Ml"Jncatch"Transter-Encod1nq":"chunked")."Connection":"keep-alive"\Sentry:: captureException($exception);Sresponse = sthis→>response→>errorinternalError selt::MESSAGE GENERALEXCEPTIONSEARCHING="CF-Ray":L"9t80debödb60dcsa-S0F"J,RateLimicexcepcion excepczon excends excepcion = so it talls through to the last catch"Strict-Transport-Secur1ty":"max-aqe=31536008* 1ncLudeSubDomains: preload")n• Reports to Sentry as a 500 internal error (noisy!)accent-encodino"• Returns errorInternalError to the client (extension shows "something went wrona")"access-control-allow-credentials": ["false"]."server-timing": ["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",• The user has no idea this is transientThis is the wrong outcome for a transient 429. There's no retry, no backoff, no useful UX.Contirmed callers"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],"So+-Cookie"." c+hm-Stlirtd0aXVr.kSandas6hzVVKhzTn0BidvMaheCtm0V-1778163675-1.0.1CrmController.php:84Sresponse = ScrmService->find(Sname, Sscopes):07-May-26 14:51:15 GMT; domain=.hubapi.com; Http0nly; Secure; SameSite=None"],"Report-To":["{"endpoints\":[{* Bul lhornSearchCommand (CLI debug only). So yes - fand() is essenttally controller-only. It is a synchronous request driven by user typing in the Chrome"unl".httns:la.nel.cloudflane.com./renon+W/v42c=NVA1cVTPQfVm32anS0#xVF/sd2RNWhat should hannen on rate limit\"group)":\"cf-nel\","max_age\":604800}"],"NEL":["{\"success_fraction\":0.01,"report to":|"cf-nel\"."max age":604800}"]"Server": ["cloudflare"]}} {This is a cunchronous HTTD reauest — we canlt releace-and-retrv like a ich Ontions ordered hv what I'd recommend.(a) Translate RateLimitException → HTTP 429 with Retrv-After header. This is the standard wav.D php} catch (RateLimitException $e) {return Sthis->response->setStatusCode(429)"correlation_ 1d":"95256555-ec98-4541-b9za-adta/Sboyeab",»ertrortoomanynequessl ern search race-tamared, predse reury shorcty.e"trace_10":C/AD8565-905t-4604-9405-0e5b551e5545"The frontend then shows a friendly "too many searches, retry in N seconds" instead of a generic error. No Sentry noise.(b) Inside find(), retry once with a short bounded sleep() (similar to searchCallByRecordingURLToken). HubSpot's SECONDLY policy has retry_after = 1 . Asinale 1sln-reauest retry.wouldlahsorh.the.most.common.case//secondlvlhurst Can.retries.at=a.svnchronousHTiTD reauest.shouldnlfhlock 10s/for TEN_SECONDI( Dunit cachofalures, (achesitreaber wit T. 0 il o ech an exception, butit does cache sucestil empy arcys. The 8009 eacthias et fandlresults actually helps absorb pressure under typina/repeat searches — that's good, leave it.Recommendation: (a) + (b) combined. Catch RateLimitException inside find(), retry once after min(SretryAfter, 1) s, and if it still fails, let it bubble: controllermaps it to HTTP 429 with Retrv-After7. The Syictind cleen(1) Retrv in searchcall cForPeriodBvPade cearchcal BvRecordinauRLTokenCurrent code• Service.php:1584-15993 catch (Fycention Ceycention)Sthis->logger→>info('(HubSpot) Search calls for period failed'. [...J):OK lets make it extremely simple. Only consider eclient- phpffL220-229 for CHubspotPaginationservice.php#fL162-198 lwill remove it from finPo. 4 spac...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
15388
|
686
|
40
|
2026-05-11T06:47:46.096348+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778482066096_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
True
|
meet.google.com/mie-gawc-dsi?authuser=lukas.kovali meet.google.com/mie-gawc-dsi?authuser=lukas.kovalik@jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
New Tab
Close tab
Meet - Daily - Platform
Close ta New Tab
Close tab
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.
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
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.
Aneliya Angelova
User profile picture User profile picture 4 others
4 others...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"New Tab","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":false},{"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":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.11777778,"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.11777778,"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.16555555,"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":true,"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":17,"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":17,"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.77916664,"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.9232639,"top":0.2911111,"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.9010417,"top":0.28666666,"width":0.09895831,"height":0.045},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":17,"bounds":{"left":0.753125,"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.91180557,"top":0.27611113,"width":0.08819443,"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.05590272,"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.03368056,"height":0.045},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":17,"bounds":{"left":0.87951386,"top":0.36277777,"width":0.07673611,"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":"Aneliya Angelova","depth":17,"bounds":{"left":0.753125,"top":0.6205556,"width":0.088541664,"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"}]...
|
414451353454061799
|
-6606244926570988780
|
app_switch
|
accessibility
|
NULL
|
New Tab
Close tab
Meet - Daily - Platform
Close ta New Tab
Close tab
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.
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
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.
Aneliya Angelova
User profile picture User profile picture 4 others
4 others...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
15447
|
688
|
40
|
2026-05-11T06:51:00.197136+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778482260197_m1.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelplah|meet.google.com/mie-gawc-dsi?authuser=[EMAIL] - Platform - nowNikolay Yankov (Presenting)100% L8•Mon 11 May 9:51:009+FleEditD €circiecicursorgithub• sonarsint |Selectionoauosseexamoles/pet-convers.abon(1 error_response.jsonrequestsoncrm-task-verification.md# HUBSPOT_WEBHOOK_WORKFLOW.md* INTERNAL_WEBHOOK_CONFIGURATION.mdnudge-performance-analysis.md• api.phpconsoe.phs• customer_apl.phpsmocooed.one•*090000:0Q8• Mon 11 May 9:50DeO 0(1 activity-examolejson() activities-listjson() toois-listjpon mepdoes › mep › (1 100is-list./s0n › () result › []toois > () 0 › () inputSchema › () properties » () date_from() exemple_respensejpon(7 tools-list.json docs/"jsoorpc": "2.0",description" search and browse recoroto vosce catts and vioco seetinos (pnone calts, 200m, Google Heet, Wacrosort Teals), Use "query" to search by wnat was discussed - e..propcrta a*Teseripton')* Seares by wut vas discussed, Natural Lngage or keyvores, Ecapless 'pricing ebjections, 'conpetitor Salesterce nentienes", "BANT buéget discussion'.aatetrot"Lype! "stri"Return conversations that started on of after this date. 150 8601 fornat (YYYY-14-00).*|"type"t "string""Return conversations that started on or before this date. IS0 8601 fornat (YMY-HM-p0).*duration sin"t"description": "Mininun conversation daration in minutes."SonarQubeĐmд +-15-reindex-streas-nodel-hydration→ origin/JY-20742-вcр-poc (forced update)•ts-re oeiy: fesesoo-gueysrat.iendating 78660b3786.66737e829c/ Coоle/ 0tA / FoCKX/Cte. teActivity TrackoCcomsnd, sheortsCallbackService.phptedReportsCallbackServiceTest.phpNikolay IvanovNikolay Yankov4 othersSteliyan Georgiev9:50 AM | Daily - PlatformLukas Kovalik2:33...
|
NULL
|
-1537102286789943941
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelplah|meet.google.com/mie-gawc-dsi?authuser=[EMAIL] - Platform - nowNikolay Yankov (Presenting)100% L8•Mon 11 May 9:51:009+FleEditD €circiecicursorgithub• sonarsint |Selectionoauosseexamoles/pet-convers.abon(1 error_response.jsonrequestsoncrm-task-verification.md# HUBSPOT_WEBHOOK_WORKFLOW.md* INTERNAL_WEBHOOK_CONFIGURATION.mdnudge-performance-analysis.md• api.phpconsoe.phs• customer_apl.phpsmocooed.one•*090000:0Q8• Mon 11 May 9:50DeO 0(1 activity-examolejson() activities-listjson() toois-listjpon mepdoes › mep › (1 100is-list./s0n › () result › []toois > () 0 › () inputSchema › () properties » () date_from() exemple_respensejpon(7 tools-list.json docs/"jsoorpc": "2.0",description" search and browse recoroto vosce catts and vioco seetinos (pnone calts, 200m, Google Heet, Wacrosort Teals), Use "query" to search by wnat was discussed - e..propcrta a*Teseripton')* Seares by wut vas discussed, Natural Lngage or keyvores, Ecapless 'pricing ebjections, 'conpetitor Salesterce nentienes", "BANT buéget discussion'.aatetrot"Lype! "stri"Return conversations that started on of after this date. 150 8601 fornat (YYYY-14-00).*|"type"t "string""Return conversations that started on or before this date. IS0 8601 fornat (YMY-HM-p0).*duration sin"t"description": "Mininun conversation daration in minutes."SonarQubeĐmд +-15-reindex-streas-nodel-hydration→ origin/JY-20742-вcр-poc (forced update)•ts-re oeiy: fesesoo-gueysrat.iendating 78660b3786.66737e829c/ Coоle/ 0tA / FoCKX/Cte. teActivity TrackoCcomsnd, sheortsCallbackService.phptedReportsCallbackServiceTest.phpNikolay IvanovNikolay Yankov4 othersSteliyan Georgiev9:50 AM | Daily - PlatformLukas Kovalik2:33...
|
15446
|
NULL
|
NULL
|
NULL
|
|
15531
|
690
|
40
|
2026-05-11T06:58:10.867235+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778482690867_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
True
|
meet.google.com/mie-gawc-dsi?authuser=lukas.kovali meet.google.com/mie-gawc-dsi?authuser=lukas.kovalik@jiminny.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.
Nikolay Yankov
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.
Galya Dimitrova
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....
|
[{"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":17,"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":17,"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":"Nikolay Yankov","depth":17,"bounds":{"left":0.753125,"top":0.36277777,"width":0.07673611,"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.90416664,"top":0.27611113,"width":0.09583336,"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.048263907,"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.026041627,"height":0.045},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":17,"bounds":{"left":0.87951386,"top":0.36277777,"width":0.08194444,"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.77916664,"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.9232639,"top":0.54888886,"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.9010417,"top":0.54444444,"width":0.09895831,"height":0.045},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-4572074015665413225
|
-6461709725053322492
|
visual_change
|
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.
Nikolay Yankov
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.
Galya Dimitrova
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....
|
NULL
|
NULL
|
NULL
|
NULL
|
|
15584
|
692
|
40
|
2026-05-11T07:02:25.901704+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778482945901_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
True
|
meet.google.com/mie-gawc-dsi?authuser=lukas.kovali meet.google.com/mie-gawc-dsi?authuser=lukas.kovalik@jiminny.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
You left the meeting
You left the meeting
Rejoin
Rejoin
Return to home screen
Return to home screen
How was the audio and video?
How was the audio and video?
Rate the meeting 1 star out of 5.
Rate the meeting 2 stars out of 5.
Rate the meeting 3 stars out of 5.
Rate the meeting 4 stars out of 5.
Rate the meeting 5 stars out of 5.
Very bad
Very good
Feedback
Feedback
60
Returning to home screen
Galya Dimitrova has left the meeting
Background is no longer replaced...
|
[{"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":"You left the meeting","depth":10,"bounds":{"left":0.4045139,"top":0.18333334,"width":0.22465278,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You left the meeting","depth":11,"bounds":{"left":0.4045139,"top":0.18277778,"width":0.22465278,"height":0.050555557},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rejoin","depth":11,"bounds":{"left":0.41493055,"top":0.27222222,"width":0.062152777,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Rejoin","depth":13,"bounds":{"left":0.43229166,"top":0.28444445,"width":0.027430555,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Return to home screen","depth":11,"bounds":{"left":0.4826389,"top":0.27222222,"width":0.13611111,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Return to home screen","depth":13,"bounds":{"left":0.49930555,"top":0.28444445,"width":0.10277778,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"How was the audio and video?","depth":10,"bounds":{"left":0.41284722,"top":0.39222223,"width":0.20833333,"height":0.046666667},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How was the audio and video?","depth":11,"bounds":{"left":0.41284722,"top":0.39444444,"width":0.15729167,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Rate the meeting 1 star out of 5.","depth":10,"bounds":{"left":0.41631943,"top":0.43888888,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Rate the meeting 2 stars out of 5.","depth":10,"bounds":{"left":0.45833334,"top":0.43888888,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Rate the meeting 3 stars out of 5.","depth":10,"bounds":{"left":0.5003472,"top":0.43888888,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Rate the meeting 4 stars out of 5.","depth":10,"bounds":{"left":0.54236114,"top":0.43888888,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Rate the meeting 5 stars out of 5.","depth":10,"bounds":{"left":0.584375,"top":0.43888888,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Very bad","depth":11,"bounds":{"left":0.41979167,"top":0.49333334,"width":0.034027778,"height":0.016111111},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Very good","depth":11,"bounds":{"left":0.575,"top":0.49333334,"width":0.03923611,"height":0.016111111},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Feedback","depth":11,"bounds":{"left":0.03784722,"top":0.95111114,"width":0.081597224,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feedback","depth":13,"bounds":{"left":0.06423611,"top":0.9633333,"width":0.044097222,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"60","depth":12,"bounds":{"left":0.061458334,"top":0.11666667,"width":0.011111111,"height":0.018333333},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Returning to home screen","depth":12,"bounds":{"left":0.09201389,"top":0.11666667,"width":0.11423611,"height":0.018333333},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Galya Dimitrova has left the meeting","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Background is no longer replaced","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-4899997645411447792
|
5317091124962570118
|
visual_change
|
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
You left the meeting
You left the meeting
Rejoin
Rejoin
Return to home screen
Return to home screen
How was the audio and video?
How was the audio and video?
Rate the meeting 1 star out of 5.
Rate the meeting 2 stars out of 5.
Rate the meeting 3 stars out of 5.
Rate the meeting 4 stars out of 5.
Rate the meeting 5 stars out of 5.
Very bad
Very good
Feedback
Feedback
60
Returning to home screen
Galya Dimitrova has left the meeting
Background is no longer replaced...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
15669
|
695
|
40
|
2026-05-11T07:07:49.073746+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778483269073_m2.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
65
1
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
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
{
// First try to get Retry-After from response headers
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
if (method_exists($e, 'getResponseBody')) {
$body = $e->getResponseBody();
if (is_string($body)) {
$body = json_decode($body, true) ?? [];
}
$policyName = $body['policyName'] ?? $body['policy'] ?? $body['context']['policyName'] ?? null;
if ($policyName === 'TEN_SECONDLY_ROLLING' || $policyName === 'ten_secondly_rolling') {
return 10;
}
if ($policyName === 'SECONDLY' || $policyName === 'secondly') {
return 1;
}
}
$this->log->warning('[Hubspot] No retry-after header or policy name found, using default', [
'exception_class' => get_class($e),
]);
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* Execute a search request against HubSpot CRM objects with rate limiting.
*
* @param string $objectType The object type ('deals', 'companies', 'contacts', 'calls')
* @param array<string, mixed> $payload The search payload with filters, sorts, properties, etc.
* @return array The search response with 'results', 'total', 'paging' keys
* @throws RateLimitException When rate limit is hit
* @throws HubspotException On API errors
*/
public function search(string $objectType, array $payload): array
{
$endpoint = self::BASE_URL . "/crm/v3/objects/{$objectType}/search";
return $this->executeRequest(function () use ($endpoint, $payload) {
$response = $this->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
});
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
//
// $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
// $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
// $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
// $body = json_decode((string) $response->getBody(), true);
//
// \Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
// \Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
// \Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
// \Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
// } catch (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);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All...
|
[{"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.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.35605052,"top":0.17478053,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"65","depth":4,"bounds":{"left":0.36602393,"top":0.17478053,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.37832448,"top":0.17478053,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.38763297,"top":0.17478053,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39660904,"top":0.17318435,"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.4039229,"top":0.17318435,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n\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 try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n 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 // First try to get Retry-After from response headers\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n if (method_exists($e, 'getResponseBody')) {\n $body = $e->getResponseBody();\n if (is_string($body)) {\n $body = json_decode($body, true) ?? [];\n }\n\n $policyName = $body['policyName'] ?? $body['policy'] ?? $body['context']['policyName'] ?? null;\n\n if ($policyName === 'TEN_SECONDLY_ROLLING' || $policyName === 'ten_secondly_rolling') {\n return 10;\n }\n if ($policyName === 'SECONDLY' || $policyName === 'secondly') {\n return 1;\n }\n }\n\n $this->log->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 getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * Execute a search request against HubSpot CRM objects with rate limiting.\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts', 'calls')\n * @param array<string, mixed> $payload The search payload with filters, sorts, properties, etc.\n * @return array The search response with 'results', 'total', 'paging' keys\n * @throws RateLimitException When rate limit is hit\n * @throws HubspotException On API errors\n */\n public function search(string $objectType, array $payload): array\n {\n $endpoint = self::BASE_URL . \"/crm/v3/objects/{$objectType}/search\";\n\n return $this->executeRequest(function () use ($endpoint, $payload) {\n $response = $this->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n });\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n//\n// $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n// $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n// $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n// $body = json_decode((string) $response->getBody(), true);\n//\n// \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n// \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n// \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n// \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n// } catch (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 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 try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n 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 // First try to get Retry-After from response headers\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n if (method_exists($e, 'getResponseBody')) {\n $body = $e->getResponseBody();\n if (is_string($body)) {\n $body = json_decode($body, true) ?? [];\n }\n\n $policyName = $body['policyName'] ?? $body['policy'] ?? $body['context']['policyName'] ?? null;\n\n if ($policyName === 'TEN_SECONDLY_ROLLING' || $policyName === 'ten_secondly_rolling') {\n return 10;\n }\n if ($policyName === 'SECONDLY' || $policyName === 'secondly') {\n return 1;\n }\n }\n\n $this->log->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 getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * Execute a search request against HubSpot CRM objects with rate limiting.\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts', 'calls')\n * @param array<string, mixed> $payload The search payload with filters, sorts, properties, etc.\n * @return array The search response with 'results', 'total', 'paging' keys\n * @throws RateLimitException When rate limit is hit\n * @throws HubspotException On API errors\n */\n public function search(string $objectType, array $payload): array\n {\n $endpoint = self::BASE_URL . \"/crm/v3/objects/{$objectType}/search\";\n\n return $this->executeRequest(function () use ($endpoint, $payload) {\n $response = $this->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n });\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n//\n// $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n// $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n// $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n// $body = json_decode((string) $response->getBody(), true);\n//\n// \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n// \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n// \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n// \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n// } catch (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":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":"19","depth":4,"bounds":{"left":0.6296542,"top":0.10055866,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6409575,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.64827126,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","depth":4,"bounds":{"left":0.43018618,"top":0.09736632,"width":0.56981385,"height":0.632083},"on_screen":true,"lines":[{"char_start":207,"char_count":30,"bounds":{"left":0.43018618,"top":0.0,"width":0.07513298,"height":0.014365523}},{"char_start":237,"char_count":36,"bounds":{"left":0.43018618,"top":0.0,"width":0.09075798,"height":0.014365523}},{"char_start":273,"char_count":32,"bounds":{"left":0.43018618,"top":0.0,"width":0.080119684,"height":0.014365523}},{"char_start":305,"char_count":79,"bounds":{"left":0.43018618,"top":0.0,"width":0.20212767,"height":0.014365523}},{"char_start":384,"char_count":18,"bounds":{"left":0.43018618,"top":0.0,"width":0.043882977,"height":0.014365523}},{"char_start":402,"char_count":21,"bounds":{"left":0.43018618,"top":0.0,"width":0.051861703,"height":0.014365523}},{"char_start":423,"char_count":48,"bounds":{"left":0.43018618,"top":0.008778931,"width":0.12167553,"height":0.014365523}},{"char_start":471,"char_count":72,"bounds":{"left":0.43018618,"top":0.026336791,"width":0.18384309,"height":0.014365523}},{"char_start":543,"char_count":40,"bounds":{"left":0.43018618,"top":0.043894652,"width":0.10106383,"height":0.014365523}},{"char_start":583,"char_count":41,"bounds":{"left":0.43018618,"top":0.061452515,"width":0.10372341,"height":0.014365523}},{"char_start":624,"char_count":72,"bounds":{"left":0.43018618,"top":0.079010375,"width":0.18384309,"height":0.014365523}},{"char_start":696,"char_count":219,"bounds":{"left":0.43018618,"top":0.096568234,"width":0.56515956,"height":0.014365523}},{"char_start":915,"char_count":83,"bounds":{"left":0.43018618,"top":0.11412609,"width":0.21243352,"height":0.014365523}},{"char_start":998,"char_count":20,"bounds":{"left":0.43018618,"top":0.13168396,"width":0.04920213,"height":0.014365523}},{"char_start":1018,"char_count":17,"bounds":{"left":0.43018618,"top":0.14924182,"width":0.041223403,"height":0.014365523}},{"char_start":1035,"char_count":203,"bounds":{"left":0.43018618,"top":0.16679968,"width":0.52360374,"height":0.014365523}},{"char_start":1238,"char_count":22,"bounds":{"left":0.43018618,"top":0.18435754,"width":0.05418883,"height":0.014365523}},{"char_start":1260,"char_count":23,"bounds":{"left":0.43018618,"top":0.2019154,"width":0.056848403,"height":0.014365523}},{"char_start":1283,"char_count":10,"bounds":{"left":0.43018618,"top":0.21947326,"width":0.023271276,"height":0.014365523}},{"char_start":1293,"char_count":27,"bounds":{"left":0.43018618,"top":0.23703113,"width":0.06715426,"height":0.014365523}},{"char_start":1320,"char_count":26,"bounds":{"left":0.43018618,"top":0.254589,"width":0.06482713,"height":0.014365523}},{"char_start":1346,"char_count":23,"bounds":{"left":0.43018618,"top":0.27214685,"width":0.056848403,"height":0.014365523}},{"char_start":1369,"char_count":28,"bounds":{"left":0.43018618,"top":0.2897047,"width":0.06981383,"height":0.014365523}},{"char_start":1397,"char_count":57,"bounds":{"left":0.43018618,"top":0.30726257,"width":0.14494681,"height":0.014365523}}],"value":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
3414566939245501088
|
-2844755624506554268
|
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
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
65
1
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
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
{
// First try to get Retry-After from response headers
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
if (method_exists($e, 'getResponseBody')) {
$body = $e->getResponseBody();
if (is_string($body)) {
$body = json_decode($body, true) ?? [];
}
$policyName = $body['policyName'] ?? $body['policy'] ?? $body['context']['policyName'] ?? null;
if ($policyName === 'TEN_SECONDLY_ROLLING' || $policyName === 'ten_secondly_rolling') {
return 10;
}
if ($policyName === 'SECONDLY' || $policyName === 'secondly') {
return 1;
}
}
$this->log->warning('[Hubspot] No retry-after header or policy name found, using default', [
'exception_class' => get_class($e),
]);
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* Execute a search request against HubSpot CRM objects with rate limiting.
*
* @param string $objectType The object type ('deals', 'companies', 'contacts', 'calls')
* @param array<string, mixed> $payload The search payload with filters, sorts, properties, etc.
* @return array The search response with 'results', 'total', 'paging' keys
* @throws RateLimitException When rate limit is hit
* @throws HubspotException On API errors
*/
public function search(string $objectType, array $payload): array
{
$endpoint = self::BASE_URL . "/crm/v3/objects/{$objectType}/search";
return $this->executeRequest(function () use ($endpoint, $payload) {
$response = $this->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
});
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
//
// $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
// $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
// $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
// $body = json_decode((string) $response->getBody(), true);
//
// \Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
// \Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
// \Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
// \Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
// } catch (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);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All...
|
15667
|
NULL
|
NULL
|
NULL
|
|
15767
|
697
|
40
|
2026-05-11T07:13:21.305203+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778483601305_m2.jpg...
|
Notion Calendar
|
NULL
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
NotionProjectMISTOMrTavsco.s%9 JY-20725-handle-HS- NotionProjectMISTOMrTavsco.s%9 JY-20725-handle-HS-search-rate-limit© HubspotPaginationService.php>M lustCalli© HubspotSyncStrategyBase.php> @ PushSummaryToCrm> D RingCentral> D ZoomPhone© MatchactivityermData.php© ermactivilyservice.phg© ActivityChangeCatego© AssignOwnership.php© ConferenceCrmMatchi© DeleteActivities.php© DeleteTeamChurnDate© DeleteTeamsRetentior©HardDeleteActivities.pc) HarcDeleteacuivity.onc) keindexroraccouniJo!© ReindexForContactJokC) ReindexForgroup.Job.r© ReindexForLeadJob.pt(C) ReindexForOpportunit© ReindexForUserJob.pr(C) RetrvActivitvSvnc.00.1l© SyncActivity.php(C) TeardownStream.ohoM Ai AutomationM A Renorts> D Audiov D AutomatedReports© RequestGenerateAskJi© RequestGenerateRepo© SendReportExpiringso© SendReportJob.php© SendReportMailJob.ph© SendReportNotGenera› D Calendarv DCrm~ D Delete© DeleteAccountJob.l©DeleteContactJob.f* DeleteCrmEntity Tra© DeleteLeadJob.php© DeleteOpportunityJ© VerifyActivityCrmTa> D Hubspot> D Salesforce©AutologDelayedToCrm©CheckAndRetryRemotr© CreateFollowupActivit!C) CreateNotes.oho(C) MatchActivitvCrmbate(C) SaveActivitv nhnc MatchermData.onouse ILLuminate \Contracts \Queue \ShouLdBeUnique;use "Luminate contracts Queve Shou doveue:use Illuminate\Database\Connection;use Illuminate \Queue \InteractsWithQueue;use Illuminate\Queue|SerializesModels;use iLuminate Support Facades Loa:use Jiminny\Component\Queue\Constants;use Jiminny\Exceptions\InvalidArgumentException;use Jiminny|Jobs\Job;Juse Jiminny\Jobs\MiddLeware\HandLeHubspotRateLimit;use Jiminny|Models\Activity;use Jiminny\Models\Crm\Configuration;use Jiminny\Repositories\ActivityRepository;use Jiminny|Services\Crm\CrmActivityService;use Psr\Container\ContainerExceptionInterface;use Psr\Container\NotFoundExceptionInterface;use Throwable;class MatchActivityCrmData extends Job implements ShouldQueue, ShouldBeUniqueuse InteractsWithQueue;use SerializesModels;public int $tries = 3;10 usagesprivate int Sactivitvid:orivate ?Confiauration sfronConfiauration:orivate hool SremoteSearch.public function middleware(): arrayf…..}public function _construct(int SactivityId,?Configuration $fromConfiguration = null, ]bool SremoteSearch = false,D4...}public function uniqueld(): stringf...public function timeout(): intf...F1 usagepublic function uniqueFor(): intf….7rctand vour Laravel ann code II Generate II Don't Show Anvmore (todav Q•08)© SyncRelatedActivityManager.php© ProspectCache.phpС Cпескапокetrукemotematch.ongM|X8AYL Lukas Kovalik's No..E custom.log x = laravel.logA SF U# console [PKOb.A console [EU)[2026-05-07 14:21:15] Local"neaders".?"Date": ["Thu,07 May 2026 14"Loncent-lyoe". "applicac!"Transter-Encoding": "chutA Home"CF-Ray":"9t80deb8dbo0dc.EA DSK Report 2023POS PAYMENT 02.01.2023 13...= Report 2025* BudgetReport 2024••• Morelravorites"Vary": ["origin,acceot-encodino"O YEAR 2026App replacement"server-timing": ["hcid; de2 Read later© LOGS© Report 2024"Set-Cookip"."" cfhm=.b Videos07-May-26 14:51:15 GMT;4 Todo"Report-To":["{\"endpoints\": ITest\"urz\":\"https:|V\\/a.nelDaily\"group\" :\"cf-nell",\"max_age\":604800}"],Agents"NEL" : ["{"success_fraction\":0.01,\"report_to\":\"cf-nel\",\"max_age\":604800}"],"Server": ["cloudflare"]1} €"correlation_id": "95236535-"trace_10":"C/ab8565-905t-4Workspace& Quick Note• Work• KnowledgedeasPrivateFinance hubE Home viewsIntegration-appWork Knowledaetesting keyboard4 TodoA YEAP 2026.New pagePersonal HomeO LOGS* Budget5) ApartmárDautorZ New chat 80<>Work KnowledgeCRMO CRM30 ll"suppon Dally• In 4h 4/ m100% C4 & • Mon 11 May 10:13:20Edited Feb 24o Share v*...CRMAll about CRM ProvidersCRM Providers• Salesforce> Hubspot8 Close• PipeDrive(c) CopperBullhorn( Integration appComponents& Add ContactsCRM update from diallersCRM refactoring@ General overview@ OnDemand CRM filtersAuthOpportunity → contactsCodebaseInfrastructuretệ: Migrate Provider...
|
NULL
|
2472892194059386079
|
NULL
|
click
|
ocr
|
NULL
|
NotionProjectMISTOMrTavsco.s%9 JY-20725-handle-HS- NotionProjectMISTOMrTavsco.s%9 JY-20725-handle-HS-search-rate-limit© HubspotPaginationService.php>M lustCalli© HubspotSyncStrategyBase.php> @ PushSummaryToCrm> D RingCentral> D ZoomPhone© MatchactivityermData.php© ermactivilyservice.phg© ActivityChangeCatego© AssignOwnership.php© ConferenceCrmMatchi© DeleteActivities.php© DeleteTeamChurnDate© DeleteTeamsRetentior©HardDeleteActivities.pc) HarcDeleteacuivity.onc) keindexroraccouniJo!© ReindexForContactJokC) ReindexForgroup.Job.r© ReindexForLeadJob.pt(C) ReindexForOpportunit© ReindexForUserJob.pr(C) RetrvActivitvSvnc.00.1l© SyncActivity.php(C) TeardownStream.ohoM Ai AutomationM A Renorts> D Audiov D AutomatedReports© RequestGenerateAskJi© RequestGenerateRepo© SendReportExpiringso© SendReportJob.php© SendReportMailJob.ph© SendReportNotGenera› D Calendarv DCrm~ D Delete© DeleteAccountJob.l©DeleteContactJob.f* DeleteCrmEntity Tra© DeleteLeadJob.php© DeleteOpportunityJ© VerifyActivityCrmTa> D Hubspot> D Salesforce©AutologDelayedToCrm©CheckAndRetryRemotr© CreateFollowupActivit!C) CreateNotes.oho(C) MatchActivitvCrmbate(C) SaveActivitv nhnc MatchermData.onouse ILLuminate \Contracts \Queue \ShouLdBeUnique;use "Luminate contracts Queve Shou doveue:use Illuminate\Database\Connection;use Illuminate \Queue \InteractsWithQueue;use Illuminate\Queue|SerializesModels;use iLuminate Support Facades Loa:use Jiminny\Component\Queue\Constants;use Jiminny\Exceptions\InvalidArgumentException;use Jiminny|Jobs\Job;Juse Jiminny\Jobs\MiddLeware\HandLeHubspotRateLimit;use Jiminny|Models\Activity;use Jiminny\Models\Crm\Configuration;use Jiminny\Repositories\ActivityRepository;use Jiminny|Services\Crm\CrmActivityService;use Psr\Container\ContainerExceptionInterface;use Psr\Container\NotFoundExceptionInterface;use Throwable;class MatchActivityCrmData extends Job implements ShouldQueue, ShouldBeUniqueuse InteractsWithQueue;use SerializesModels;public int $tries = 3;10 usagesprivate int Sactivitvid:orivate ?Confiauration sfronConfiauration:orivate hool SremoteSearch.public function middleware(): arrayf…..}public function _construct(int SactivityId,?Configuration $fromConfiguration = null, ]bool SremoteSearch = false,D4...}public function uniqueld(): stringf...public function timeout(): intf...F1 usagepublic function uniqueFor(): intf….7rctand vour Laravel ann code II Generate II Don't Show Anvmore (todav Q•08)© SyncRelatedActivityManager.php© ProspectCache.phpС Cпескапокetrукemotematch.ongM|X8AYL Lukas Kovalik's No..E custom.log x = laravel.logA SF U# console [PKOb.A console [EU)[2026-05-07 14:21:15] Local"neaders".?"Date": ["Thu,07 May 2026 14"Loncent-lyoe". "applicac!"Transter-Encoding": "chutA Home"CF-Ray":"9t80deb8dbo0dc.EA DSK Report 2023POS PAYMENT 02.01.2023 13...= Report 2025* BudgetReport 2024••• Morelravorites"Vary": ["origin,acceot-encodino"O YEAR 2026App replacement"server-timing": ["hcid; de2 Read later© LOGS© Report 2024"Set-Cookip"."" cfhm=.b Videos07-May-26 14:51:15 GMT;4 Todo"Report-To":["{\"endpoints\": ITest\"urz\":\"https:|V\\/a.nelDaily\"group\" :\"cf-nell",\"max_age\":604800}"],Agents"NEL" : ["{"success_fraction\":0.01,\"report_to\":\"cf-nel\",\"max_age\":604800}"],"Server": ["cloudflare"]1} €"correlation_id": "95236535-"trace_10":"C/ab8565-905t-4Workspace& Quick Note• Work• KnowledgedeasPrivateFinance hubE Home viewsIntegration-appWork Knowledaetesting keyboard4 TodoA YEAP 2026.New pagePersonal HomeO LOGS* Budget5) ApartmárDautorZ New chat 80<>Work KnowledgeCRMO CRM30 ll"suppon Dally• In 4h 4/ m100% C4 & • Mon 11 May 10:13:20Edited Feb 24o Share v*...CRMAll about CRM ProvidersCRM Providers• Salesforce> Hubspot8 Close• PipeDrive(c) CopperBullhorn( Integration appComponents& Add ContactsCRM update from diallersCRM refactoring@ General overview@ OnDemand CRM filtersAuthOpportunity → contactsCodebaseInfrastructuretệ: Migrate Provider...
|
15765
|
NULL
|
NULL
|
NULL
|
|
16731
|
746
|
40
|
2026-05-11T09:19:38.620890+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778491178620_m1.jpg...
|
PhpStorm
|
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Include non-project items
Preview
Filter
Open in F Include non-project items
Preview
Filter
Open in Find Tool Window
PLayback-
activity-playback-available.email.mustache resources/views/emails/postmark-templates/email
activity-playback-available.subject.mustache resources/views/emails/postmark-templates/email
2021-02-12-emea-themes-da-add.csv contrib/playback-themes
2021_01_05-emea-themes-de-add.csv contrib/playback-themes
2021_01_05-emea-themes-en-add.csv contrib/playback-themes
2021_01_05-emea-themes-en-remove.csv contrib/playback-themes
2021_01_05-emea-themes-es-add.csv contrib/playback-themes
2021_01_05-emea-themes-fr-add.csv contrib/playback-themes
2021_01_05-emea-themes-it-add.csv contrib/playback-themes
2021_01_05-emea-themes-nl-add.csv contrib/playback-themes
2021_01_05-emea-themes-pt-add.csv contrib/playback-themes
2021_01_05-emea-themes-sv-add.csv contrib/playback-themes
2021_06_25-emea-themes-pl-add.csv contrib/playback-themes...
|
[{"role":"AXCheckBox","text [{"role":"AXCheckBox","text":"Include non-project items","depth":2,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Preview","depth":2,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter","depth":2,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Find Tool Window","depth":2,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"PLayback-","depth":1,"on_screen":true,"value":"PLayback-","role_description":"text field","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"activity-playback-available.email.mustache resources/views/emails/postmark-templates/email","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"activity-playback-available.subject.mustache resources/views/emails/postmark-templates/email","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2021-02-12-emea-themes-da-add.csv contrib/playback-themes","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2021_01_05-emea-themes-de-add.csv contrib/playback-themes","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2021_01_05-emea-themes-en-add.csv contrib/playback-themes","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2021_01_05-emea-themes-en-remove.csv contrib/playback-themes","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2021_01_05-emea-themes-es-add.csv contrib/playback-themes","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2021_01_05-emea-themes-fr-add.csv contrib/playback-themes","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2021_01_05-emea-themes-it-add.csv contrib/playback-themes","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2021_01_05-emea-themes-nl-add.csv contrib/playback-themes","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2021_01_05-emea-themes-pt-add.csv contrib/playback-themes","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2021_01_05-emea-themes-sv-add.csv contrib/playback-themes","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2021_06_25-emea-themes-pl-add.csv contrib/playback-themes","depth":2,"on_screen":true,"role_description":"text"}]...
|
-8952469557276323295
|
3213451034061031145
|
click
|
accessibility
|
NULL
|
Include non-project items
Preview
Filter
Open in F Include non-project items
Preview
Filter
Open in Find Tool Window
PLayback-
activity-playback-available.email.mustache resources/views/emails/postmark-templates/email
activity-playback-available.subject.mustache resources/views/emails/postmark-templates/email
2021-02-12-emea-themes-da-add.csv contrib/playback-themes
2021_01_05-emea-themes-de-add.csv contrib/playback-themes
2021_01_05-emea-themes-en-add.csv contrib/playback-themes
2021_01_05-emea-themes-en-remove.csv contrib/playback-themes
2021_01_05-emea-themes-es-add.csv contrib/playback-themes
2021_01_05-emea-themes-fr-add.csv contrib/playback-themes
2021_01_05-emea-themes-it-add.csv contrib/playback-themes
2021_01_05-emea-themes-nl-add.csv contrib/playback-themes
2021_01_05-emea-themes-pt-add.csv contrib/playback-themes
2021_01_05-emea-themes-sv-add.csv contrib/playback-themes
2021_06_25-emea-themes-pl-add.csv contrib/playback-themes...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
17273
|
769
|
40
|
2026-05-11T10:15:26.648880+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778494526648_m2.jpg...
|
Notion Calendar
|
NULL
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
rostmanFavouritesjiminny(* AirDrop• RecentsA Appli rostmanFavouritesjiminny(* AirDrop• RecentsA Applications9 Documents• Downloadsii lukasIcloud• iCloud Drive992 Svnc toldeLocations0 DXP4800PLUS-B5F A49 Network• CRM• Orange|• Red• Yellow• Greer• Blue• Purple• All lags..caltVIewWindowmelpscreenpipearchive.db• #recycledb.sqlite-shmdb.sqlitevi loassync.log• screenpipe.2026-05-07.0.1ogv data•2026-05-072026-05-062026-04.292026-04-27> 2026-04-25•2026-04-24> 2026-04-22• 2026-04-23• 2026-04-20• 2026.04.212026-04-172026-04-16• 2026-04-15• 2026-04-14screenpipe_sync_updated.sharchive.db-oak>?app• db.sqlite-walscreenpipe_sync.shann cettinas ison• screenpipe.db›_pipeshel"suppont Dally • In 1h 40m100% L2• Mon 11 May 13:15:26Xx Hubspot vYour team is now on the Free plan with 1 admin. You retain editing access and other members are read-only. View team permissions to see who can edit, or upgrade to restore collaborationCOLLECTIONSPost meetings scheduledGET get meetingPost aet link to task> POST Create Contact with AssociationHubspotv Iteration run HSGET Read Copyea. An error occurred.eg. successful operationv Iteration run Search HS> Iournal & webhoooks v4|› OAuth> Pronertioc> RESEARCHSFAPCHPOST search contact by phonePOST search contact by emailPOST Search notesPOST Search calls v3PoSt Search related meetinas v2Post search deals› Tickets> post filter ner comnanv I onlv onen deal stadesGet engagements old associated by dealGET engagements old associated by companyGet get history of property - deal stageGET aet ucereGET SF oauth> GET Meeting outcomes per meeting> GET Read all properties new> Get Read all oronerties oldiGET old call dispositionsGEt list with associationsGET list engagements olcSustem Resource WarningSustem resources are constrained. Thesystem may not be able to generate the loadeded for this test and the cest is likely to§ Connect Git E Console E TerminaНIP Useful › Get Engagement (v1)[URL_WITH_CREDENTIALS] Notround 1//ms • 1.23 KB •CrAe.g. save kesponsetowt/htmlahercotcicn.0060.19f80e382c05f2ba5-SoRDYNAMICmust-revalidate no-cache.no-ctoremax-age=31536000; includeSubDomains; preloadoriain, Accept-Encodinafalceheid:desc-"019e02d3-6e10-7a75-8180-644e/659281d" ctr.desc-"9 806382d6102ha5-IAD"nosniff010002d2.6010.7/75-9490-6410f65Q291210000109"endpoints".""uri".*httos:/Wa.nel.cloudflare.com//report/v42s=VvJK@eaYo%28LCL%28ToN9omvzK%2F0%2BrGkNu24T5.("success fraction":0.01,"report_to":"cf-nel""max age":604800}cloudflareGlobals Vault Tools?000...
|
NULL
|
-1751847066666723340
|
NULL
|
click
|
ocr
|
NULL
|
rostmanFavouritesjiminny(* AirDrop• RecentsA Appli rostmanFavouritesjiminny(* AirDrop• RecentsA Applications9 Documents• Downloadsii lukasIcloud• iCloud Drive992 Svnc toldeLocations0 DXP4800PLUS-B5F A49 Network• CRM• Orange|• Red• Yellow• Greer• Blue• Purple• All lags..caltVIewWindowmelpscreenpipearchive.db• #recycledb.sqlite-shmdb.sqlitevi loassync.log• screenpipe.2026-05-07.0.1ogv data•2026-05-072026-05-062026-04.292026-04-27> 2026-04-25•2026-04-24> 2026-04-22• 2026-04-23• 2026-04-20• 2026.04.212026-04-172026-04-16• 2026-04-15• 2026-04-14screenpipe_sync_updated.sharchive.db-oak>?app• db.sqlite-walscreenpipe_sync.shann cettinas ison• screenpipe.db›_pipeshel"suppont Dally • In 1h 40m100% L2• Mon 11 May 13:15:26Xx Hubspot vYour team is now on the Free plan with 1 admin. You retain editing access and other members are read-only. View team permissions to see who can edit, or upgrade to restore collaborationCOLLECTIONSPost meetings scheduledGET get meetingPost aet link to task> POST Create Contact with AssociationHubspotv Iteration run HSGET Read Copyea. An error occurred.eg. successful operationv Iteration run Search HS> Iournal & webhoooks v4|› OAuth> Pronertioc> RESEARCHSFAPCHPOST search contact by phonePOST search contact by emailPOST Search notesPOST Search calls v3PoSt Search related meetinas v2Post search deals› Tickets> post filter ner comnanv I onlv onen deal stadesGet engagements old associated by dealGET engagements old associated by companyGet get history of property - deal stageGET aet ucereGET SF oauth> GET Meeting outcomes per meeting> GET Read all properties new> Get Read all oronerties oldiGET old call dispositionsGEt list with associationsGET list engagements olcSustem Resource WarningSustem resources are constrained. Thesystem may not be able to generate the loadeded for this test and the cest is likely to§ Connect Git E Console E TerminaНIP Useful › Get Engagement (v1)[URL_WITH_CREDENTIALS] Notround 1//ms • 1.23 KB •CrAe.g. save kesponsetowt/htmlahercotcicn.0060.19f80e382c05f2ba5-SoRDYNAMICmust-revalidate no-cache.no-ctoremax-age=31536000; includeSubDomains; preloadoriain, Accept-Encodinafalceheid:desc-"019e02d3-6e10-7a75-8180-644e/659281d" ctr.desc-"9 806382d6102ha5-IAD"nosniff010002d2.6010.7/75-9490-6410f65Q291210000109"endpoints".""uri".*httos:/Wa.nel.cloudflare.com//report/v42s=VvJK@eaYo%28LCL%28ToN9omvzK%2F0%2BrGkNu24T5.("success fraction":0.01,"report_to":"cf-nel""max age":604800}cloudflareGlobals Vault Tools?000...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
17284
|
768
|
40
|
2026-05-11T10:15:42.567820+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778494542567_m1.jpg...
|
Notion Calendar
|
NULL
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
iTerm2•ShellEditViewSessionScriptsProfilesWindowHe iTerm2•ShellEditViewSessionScriptsProfilesWindowHelplih# Support Daily - in 1h 45 mDOCKER881DEV (docker)H82APP (-zsh)DEV (docker)X3-zshl84-zsh100% C8• Mon 11 May 13:15:42181ffmpeg0 ₴6configcachecompiledeventsroutesviewsjiminny-worker-processing-2:jiminny-worker-processing-2_00: stoppedjiminny-worker-processing-3:jiminny-worker-processing-3_00:stoppedjiminny-worker-processing-4:jiminny-worker-processing-4_00:stoppedjiminny-worker-processing-5:jiminny-worker-processing-5_00:stoppedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: stoppedworker-analytics:worker-analytics_00: stoppedworker-conferences:worker-conferences_00: stoppedworker-crm-update:worker-crm-update_00: stoppedworker-download:worker-download_00: stoppedworker-emails:worker-emails_00: stoppedworker-nudges:worker-nudges_00: stoppedworker:worker_00: stoppedworker-audio:worker-audio_00: stoppedworker-calendar:worker-calendar_00: stoppedworker-crm-sync:worker-crm-sync_00: stoppedartisan-schedule:artisan-schedule_00: stoppedworker-es-update:worker-es-update_00: stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedartisan-schedule:artisan-schedule_00: startedjiminny-worker-processing-1:jiminny-worker-processing-1_00: startedjiminny-worker-processing-2:jiminny-worker-processing-2_00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00:startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00: startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00:startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00: startedworker-nudges:worker-nudges_00:startedroot@docker_lamp_1:/home/jiminny#php artisan jiminny: debugll88510.53ms DONE128.25ms DONE1.73ms DONE1.07ms DONE1.45ms DONE5.46ms DONEDEV...
|
NULL
|
2993393362763921113
|
NULL
|
click
|
ocr
|
NULL
|
iTerm2•ShellEditViewSessionScriptsProfilesWindowHe iTerm2•ShellEditViewSessionScriptsProfilesWindowHelplih# Support Daily - in 1h 45 mDOCKER881DEV (docker)H82APP (-zsh)DEV (docker)X3-zshl84-zsh100% C8• Mon 11 May 13:15:42181ffmpeg0 ₴6configcachecompiledeventsroutesviewsjiminny-worker-processing-2:jiminny-worker-processing-2_00: stoppedjiminny-worker-processing-3:jiminny-worker-processing-3_00:stoppedjiminny-worker-processing-4:jiminny-worker-processing-4_00:stoppedjiminny-worker-processing-5:jiminny-worker-processing-5_00:stoppedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: stoppedworker-analytics:worker-analytics_00: stoppedworker-conferences:worker-conferences_00: stoppedworker-crm-update:worker-crm-update_00: stoppedworker-download:worker-download_00: stoppedworker-emails:worker-emails_00: stoppedworker-nudges:worker-nudges_00: stoppedworker:worker_00: stoppedworker-audio:worker-audio_00: stoppedworker-calendar:worker-calendar_00: stoppedworker-crm-sync:worker-crm-sync_00: stoppedartisan-schedule:artisan-schedule_00: stoppedworker-es-update:worker-es-update_00: stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedartisan-schedule:artisan-schedule_00: startedjiminny-worker-processing-1:jiminny-worker-processing-1_00: startedjiminny-worker-processing-2:jiminny-worker-processing-2_00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00:startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00: startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00:startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00: startedworker-nudges:worker-nudges_00:startedroot@docker_lamp_1:/home/jiminny#php artisan jiminny: debugll88510.53ms DONE128.25ms DONE1.73ms DONE1.07ms DONE1.45ms DONE5.46ms DONEDEV...
|
17282
|
NULL
|
NULL
|
NULL
|
|
17392
|
771
|
40
|
2026-05-11T10:21:27.003020+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778494887003_m2.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest...
|
[{"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}]...
|
1684527879063584500
|
-8348266015821985344
|
click
|
hybrid
|
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
PhostormVIewINavicareCodeFV faVsco.js°9 JY-20725-handle-HS-search-rate-limiProiect© HubspotWebhoo© SyncRelatedActivityManager.phpyhudspotsynestrategybase.ongT SyncCrmEntitiesTrait.phpv D Pagination© HubspotPaginatC Paginationconti© ermactivityservice.phgC) Paginationstate•_ Prospectsearchstr> 0 Redisclass Cllent extends Baseclient 1mpLements Hubspotclientintertacev D ServiceTraits+Opportunitysync+ SyncermEntitiest SyncFields trait.T.WriteCrmtrait.pW Utils•WeonookC) BatchSvncCollectoC) BatchSvncRedisSerlC) Client.ohoC) ClosedDealStadesSG DealFieldsService.p© DecorateActivity.ph© FieldDefinitions.phpC) SieldTvneConverte(0) HubsnotClientinter© HubspotTokenMan© PayloadBuilder.phpG DomotoCrmOhiontl0 DocnancaMormolizec) service.ono© SyncFieldAction.ph© SyncRelatedActivitc) WebhooksyncBatc• Ca IntegrationApp139› Accessors•D ApI• contio> MDTO•D Filters• llobs• ProspectSearchStr.• ServiceTraitsC) Dataclient.ohoC) DecorateActivitv.oh149C LocalSearch.nhn(0 LocalSearchinterfal15€151152C) RemoteSearch.nhn© Service.phpv Ml istenerc154159© ConvertLeadActivite Duraol aokunencheM Motadata15€157• M Miarationououc tunction 1shubspotrateuimithrowable sel: 000lif Se instanceof BadReauestI1 $e instanceof DealApiExceptionSe instanceof ContactaniExcentionI1 $e instanceof CompanyApiExceptionSe instanceofGuzzleltto Excention ReauestExcentionneturn (int) So->aetCode0 === 429:public function parseRetryAfter(Throwable Se): intif (method exists($emethod: 'qetResponseHeaders'){sheaders = se->qetkesponsereaderso?:nSvalue = Sheaders['Retry-After'] ?? Sheaders['retry-after'] ?? null:if (is array(Svalue)) {Svalue = Svaluelol 22 null;if (is numeric(Svalue)) {return (int) svalue:Snollev = sthis->nansePo.i.cvse):if ($policy === 'TEN_SECONDLY_ROLLING') {neturn 10.if Snolicv === ISECONDLY!) *neturn1if ($policy === 'DAILY_LIMIT') {notunn kad.'exception class' => qet class(Se).return10:T DeleteCrmEntityTrait.php© Job.phpA2 467 M3 A VI II I119151100% C4console [PRODconsole fEulA console [STAGING]= laravel.log X 4 SF [jiminny@localhost]Received 429 from API1 399 /:6-05-11 10:17:04] local.INF0:Esupdacelaroer uodare sinole taroec "caroec, aculvicles, "purpose."searchaole-ooserver16-05-11 10:17:04] local. INF0:[MatchActivityCrmDatal Starting CRM data matching {"activity":613820,"remote_search":true. "set confiquration":216-05-11 10:17:04] local.INF0:Esupdatelarget Update sinqle target ""target":"activities", "purpose":"searchable-observer-update", "entityid16-05-11 10:17:04] local. INFO:6-05-1 10:17:04 LOCOL. INFOH•archactrvir ycombaral Partacioants old state sacryty 1o%enantcnants"aemnomaowraeusen nolanua":6-05-11 10:17:04] Local. INFOSocialAccountServicel Fetchina token "socialAccountd": 1499. "orovide16-05-11 10:17:04 ZocaL. INFO:retrieved "socialAccountitd".1."correlation 1d"*"ee7844816-05-11 10:17:04] Local. INFO:6-05-11 10:17:04) local.INF0:CrmOwnerResolver Intearation owner matched as CRM Owner <"dViden"«"hubsoot" "crm ownen":148. "team id"-2:6-05-11 10:17:04] Local. INFO:6-05-11 10:17:04) local.INF0:ermActivitvService Enaii domain helonas to the team. ckannina erm lookun Clactivitv idi:613820.1midi.2."e:6-05-11 10:17:04) local.INFOsed":2,"exact_matches":1,16-05-11 10:17:04] local.INF0: [ EsUpdateTarget ] Update single target {"target":"activities", "purpose":"searchable-observer-update" "entityFd16-05-11 10:17:04] local.INF0:[ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities" "entityid":613820, "collectio16-05-11 10:17:04] local.INF0:16-05-11 10:17:04] local.INF0:16-05-11 10:17:04] local.INF0:14-05-1110-17-0/1 10601 TNSN•(MatchActivi+vfnmhatal Donticinante old ctato filactivi+vll.412019 IInanticinantcll.ffuidi.1001717 Hucon idil.null. II:6-05-11 10:17:04] local.INF0:[SocialAccountServicel Fetching token {"socialAccountId":1499.16-05-11 10:17:04] local.INF0:fcocialAecoun+Convicol Tokon notriovod filcocialAccoun+tal.110:6-05-11 10:17:04] local.INF0:[EncryptedTokenManager] Generating access token. {"mode"=6-05-11 10:17:04] local.INF0: [Crm0wnerResolver] Integration owner matched as CRM OwneSiconnolation idul.un470/02"74704a29-86b2-4b3f-ae73-0"team_id":2com"} {"comid":2."e16-05-11 10:17:041 local, INF0:[CrmActivitvServicel CRM matching completed {"activity id":613818.*xact matches":"entitvld16-05-11 10:17:041 local, INF0:16-05-11 10:17:05] Local. INF0:16-05-11 10:17:051 local, INF0:MatchActivitvermbatal Startina CRM data matching ""activity":613812):6-05-11 10:17:05] Local. INF0:16-05-11 10:17:051 local, INF0::6-05-11 10:17:05] Local. INFO16-05-11 10-17-057 TocaTNSOASocial AccountService Setchina token "socialAccountid":1400 "nrovidenentitvid":615818."collectioch":true."lead id":null."coearch": true "set confiquration",aodate" "entitvidentitvid":613812."collectio""correllation 1d":"0698152e{"correlation id"."0698152*6-05-11 10•17-051 local. TNE0•id":"06981520-0a7h-46d1-05e4-ubsnoti "eom ownen".148 "team idi.2*6-05-11 10•17-051 local. TNEOIProsnectmatchi Cache local seanch hit suidentifien16-05-11 10:17:05] local.INF016-05-11 10:17:05] local.INF0:16-05-11 10:17:05] local.INF0:Honti+utdcolloctio[MatchActivityCrmData] Successfully matched CRM data {"activity":613812,"remote sear[MatchActivityCrmDatal Starting CRM data matching {"activity":613807,"remote search":true "set confiquration":216-05-11 10:17:05] local.INF0:[ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities" "entityId":613807 "collecti...
|
17389
|
NULL
|
NULL
|
NULL
|
|
17475
|
774
|
40
|
2026-05-11T10:24:11.029457+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778495051029_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
SECONDLY
Search
AND also
second required term — both must appear in same result (optional)
Source
App
Date
dd
/
mm
/
yyyy
Calendar
(blank = all dates)
From
--
:
--
To
--
:
--
Only apps
any app (blank = all)
▾
Skip apps
none skipped
▾
FTS tip: single words work best · "exact phrase" · term1 OR term2 · use AND also for required second term · times are in your local timezone · click any result to expand
49 results
▶ video
7 May 19:25
Screen
PhpStorm
/ faVsco.js – Client.php
⏱ Timeline
...true) ??
:SpolicyName = $body
'policyName'
?? Sbody
'policy'
?? null:Map pollcy names to retry delaysif (SpolicvName === 'TEN
SECONDLY
_ROLLING' |I SpolicvName === 'ten
secondly
rolling') {
… (click to expand)
▶ video
7 May 19:10
Screen
PhpStorm
/ faVsco.js – Client.php
⏱ Timeline
...true) ??
:Snolievlane = Sbod/LUpoltiev/lane:1 22 Shody
LnolieyL1L.22 п11rao nolicy names to retry delav1f SpoLicvName ==='TEN
SECONDLY
ROLLING' |I SpolicvName === 'ten
secondly
rolling') {Le
… (click to expand)
7 May 17:24
Typed
Firefox
text
⏱ Timeline
.
7 May 17:23
Typed
Firefox
text
⏱ Timeline
7 May 17:22
Typed
Firefox
text
⏱ Timeline
.
7 May 17:22
Typed
Firefox
text
⏱ Timeline
'
7 May 17:21
Typed
Firefox
text
⏱ Timeline
7 May 17:20
Typed
Firefox
text
⏱ Timeline
7 May 17:19
Typed
Firefox
text
⏱ Timeline
7 May 17:17
Typed
Firefox
text
⏱ Timeline
7 May 17:17
Typed
Firefox
text
⏱ Timeline
$
7 May 17:17
Typed
Firefox
text
⏱ Timeline
;
7 May 17:17
Typed
Firefox
text
⏱ Timeline
=
7 May 17:16
Typed
Firefox
text
⏱ Timeline
:
7 May 17:16
Typed
Firefox
text
⏱ Timeline
7 May 17:15
Typed
Firefox
text
⏱ Timeline
.
7 May 17:15
Typed
Firefox
text
⏱ Timeline
7 May 17:14
Typed
Firefox
text
⏱ Timeline
7 May 17:14
Typed
Firefox
text
⏱ Timeline
.
7 May 17:10
Typed
Firefox
text
⏱ Timeline
7 May 17:09
Typed
Firefox
text
⏱ Timeline
7 May 17:08
Typed
Firefox
text
⏱ Timeline
7 May 17:07
Typed
Firefox
text
⏱ Timeline
7 May 14:13
Typed
Claude
text
⏱ Timeline
secondly
7 May 10:58
Typed
clipboard
⏱ Timeline
...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...)
7 May 10:41
Typed...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.28823137,"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.30152926,"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.28823137,"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.30152926,"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.38962767,"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.29105717,"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.29105717,"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.3020279,"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.3131649,"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.32430187,"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.33543882,"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.4085771,"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.4085771,"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.43766624,"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.48021942,"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.5056516,"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.53008646,"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.55169547,"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.5874335,"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.6178524,"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":"AXTextField","text":"SECONDLY","depth":8,"bounds":{"left":0.4965093,"top":0.11412609,"width":0.38131648,"height":0.025538707},"on_screen":true,"value":"SECONDLY","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search","depth":8,"bounds":{"left":0.88048536,"top":0.11412609,"width":0.024933511,"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":"AND also","depth":9,"bounds":{"left":0.4965093,"top":0.15522745,"width":0.01662234,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"second required term — both must appear in same result (optional)","depth":8,"bounds":{"left":0.51579124,"top":0.14764565,"width":0.38962767,"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":"Source","depth":9,"bounds":{"left":0.4965093,"top":0.18754987,"width":0.012300532,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"App","depth":9,"bounds":{"left":0.58427525,"top":0.18754987,"width":0.006981383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date","depth":9,"bounds":{"left":0.6431183,"top":0.18754987,"width":0.008144947,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dd","depth":10,"bounds":{"left":0.65791225,"top":0.18715084,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":9,"bounds":{"left":0.66373,"top":0.18715084,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"mm","depth":10,"bounds":{"left":0.6672208,"top":0.18715084,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":9,"bounds":{"left":0.67287236,"top":0.18715084,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"yyyy","depth":10,"bounds":{"left":0.67636305,"top":0.18715084,"width":0.009640957,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Calendar","depth":9,"bounds":{"left":0.6871675,"top":0.18754987,"width":0.005319149,"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":"(blank = all dates)","depth":9,"bounds":{"left":0.69863695,"top":0.18794893,"width":0.028756648,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"From","depth":9,"bounds":{"left":0.7300532,"top":0.18754987,"width":0.008976064,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--","depth":10,"bounds":{"left":0.7456782,"top":0.18715084,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":9,"bounds":{"left":0.7513298,"top":0.18715084,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--","depth":10,"bounds":{"left":0.75482047,"top":0.18715084,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"To","depth":9,"bounds":{"left":0.7742686,"top":0.18754987,"width":0.004155585,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--","depth":10,"bounds":{"left":0.78507316,"top":0.18715084,"width":0.004654255,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":9,"bounds":{"left":0.79072475,"top":0.18715084,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--","depth":10,"bounds":{"left":0.79421544,"top":0.18715084,"width":0.0048204786,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Only apps","depth":9,"bounds":{"left":0.4965093,"top":0.21588188,"width":0.017453458,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"any app (blank = all)","depth":11,"bounds":{"left":0.51961434,"top":0.2150838,"width":0.038065158,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▾","depth":11,"bounds":{"left":0.5718085,"top":0.21628092,"width":0.0016622341,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Skip apps","depth":9,"bounds":{"left":0.5817819,"top":0.21588188,"width":0.017121011,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"none skipped","depth":11,"bounds":{"left":0.60455453,"top":0.2150838,"width":0.025265958,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▾","depth":11,"bounds":{"left":0.65674865,"top":0.21628092,"width":0.0016622341,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FTS tip: single words work best · \"exact phrase\" · term1 OR term2 · use AND also for required second term · times are in your local timezone · click any result to expand","depth":9,"bounds":{"left":0.4965093,"top":0.23902634,"width":0.29055852,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"49 results","depth":10,"bounds":{"left":0.4978391,"top":0.29209897,"width":0.017453458,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▶ video","depth":10,"bounds":{"left":0.50964093,"top":0.3367917,"width":0.012300532,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 19:25","depth":11,"bounds":{"left":0.5340758,"top":0.32043096,"width":0.021110373,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Screen","depth":11,"bounds":{"left":0.55851066,"top":0.32202715,"width":0.010139627,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PhpStorm","depth":12,"bounds":{"left":0.57130986,"top":0.32043096,"width":0.01861702,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/ faVsco.js – Client.php","depth":11,"bounds":{"left":0.5909242,"top":0.32043096,"width":0.039893616,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"bounds":{"left":0.8784907,"top":0.31923383,"width":0.022606382,"height":0.014764565},"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"...true) ??","depth":11,"bounds":{"left":0.5340758,"top":0.339585,"width":0.020279255,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":SpolicyName = $body","depth":11,"bounds":{"left":0.55502,"top":0.339585,"width":0.045545213,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'policyName'","depth":12,"bounds":{"left":0.6008976,"top":0.339585,"width":0.026097074,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"?? Sbody","depth":11,"bounds":{"left":0.62732714,"top":0.339585,"width":0.019614361,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'policy'","depth":12,"bounds":{"left":0.64727396,"top":0.339585,"width":0.014461436,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"?? null:Map pollcy names to retry delaysif (SpolicvName === 'TEN","depth":11,"bounds":{"left":0.66206783,"top":0.339585,"width":0.1349734,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SECONDLY","depth":12,"bounds":{"left":0.79737365,"top":0.339585,"width":0.022772606,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"_ROLLING' |I SpolicvName === 'ten","depth":11,"bounds":{"left":0.82047874,"top":0.339585,"width":0.07263963,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"secondly","depth":12,"bounds":{"left":0.5344083,"top":0.35514766,"width":0.018118352,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"rolling') {","depth":11,"bounds":{"left":0.55285907,"top":0.35514766,"width":0.019281914,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"… (click to expand)","depth":11,"bounds":{"left":0.57214093,"top":0.35514766,"width":0.038231384,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▶ video","depth":10,"bounds":{"left":0.50964093,"top":0.40901837,"width":0.012300532,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 19:10","depth":11,"bounds":{"left":0.5340758,"top":0.3926576,"width":0.020611702,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Screen","depth":11,"bounds":{"left":0.55801195,"top":0.3942538,"width":0.010139627,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PhpStorm","depth":12,"bounds":{"left":0.57081115,"top":0.3926576,"width":0.01861702,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/ faVsco.js – Client.php","depth":11,"bounds":{"left":0.59042555,"top":0.3926576,"width":0.039893616,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"bounds":{"left":0.8784907,"top":0.3914605,"width":0.022606382,"height":0.014764565},"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"...true) ??","depth":11,"bounds":{"left":0.5340758,"top":0.41181165,"width":0.020279255,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":Snolievlane = Sbod/LUpoltiev/lane:1 22 Shody","depth":11,"bounds":{"left":0.55502,"top":0.41181165,"width":0.09424867,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"LnolieyL1L.22 п11rao nolicy names to retry delav1f SpoLicvName ==='TEN","depth":12,"bounds":{"left":0.64960104,"top":0.41181165,"width":0.14943483,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SECONDLY","depth":13,"bounds":{"left":0.7993683,"top":0.41181165,"width":0.022772606,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ROLLING' |I SpolicvName === 'ten","depth":12,"bounds":{"left":0.8224734,"top":0.41181165,"width":0.07014628,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"secondly","depth":13,"bounds":{"left":0.5344083,"top":0.4273743,"width":0.018118352,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"rolling') {Le","depth":12,"bounds":{"left":0.55285907,"top":0.4273743,"width":0.024102394,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"… (click to expand)","depth":12,"bounds":{"left":0.57696146,"top":0.4273743,"width":0.038065158,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 17:24","depth":11,"bounds":{"left":0.5008311,"top":0.46488428,"width":0.020777926,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"bounds":{"left":0.5249335,"top":0.46648043,"width":0.008976064,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"bounds":{"left":0.53673536,"top":0.46488428,"width":0.012799202,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.5505319,"top":0.46568236,"width":0.006150266,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"bounds":{"left":0.8784907,"top":0.46368715,"width":0.022606382,"height":0.014764565},"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":".","depth":11,"bounds":{"left":0.5008311,"top":0.4840383,"width":0.0013297872,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 17:23","depth":11,"bounds":{"left":0.5008311,"top":0.5215483,"width":0.020777926,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"bounds":{"left":0.5249335,"top":0.5231444,"width":0.008976064,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"bounds":{"left":0.5365692,"top":0.5215483,"width":0.012965426,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.5505319,"top":0.5223464,"width":0.006150266,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"bounds":{"left":0.8784907,"top":0.5203512,"width":0.022606382,"height":0.014764565},"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 May 17:22","depth":11,"bounds":{"left":0.5008311,"top":0.56264967,"width":0.020777926,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"bounds":{"left":0.5249335,"top":0.5642458,"width":0.008976064,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"bounds":{"left":0.5365692,"top":0.56264967,"width":0.012799202,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.5503657,"top":0.5634477,"width":0.006150266,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"bounds":{"left":0.8784907,"top":0.5614525,"width":0.022606382,"height":0.014764565},"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":".","depth":11,"bounds":{"left":0.5008311,"top":0.5818037,"width":0.0013297872,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 17:22","depth":11,"bounds":{"left":0.5008311,"top":0.61931366,"width":0.020777926,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"bounds":{"left":0.5249335,"top":0.6209098,"width":0.008976064,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"bounds":{"left":0.5365692,"top":0.61931366,"width":0.012799202,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.5503657,"top":0.6201117,"width":0.006150266,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"bounds":{"left":0.8784907,"top":0.6181165,"width":0.022606382,"height":0.014764565},"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"'","depth":11,"bounds":{"left":0.5008311,"top":0.63846767,"width":0.0013297872,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 17:21","depth":11,"bounds":{"left":0.5008311,"top":0.67597765,"width":0.020279255,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"bounds":{"left":0.52443486,"top":0.6775738,"width":0.008976064,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"bounds":{"left":0.53607047,"top":0.67597765,"width":0.012799202,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.54986703,"top":0.67677575,"width":0.006150266,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"bounds":{"left":0.8784907,"top":0.67478055,"width":0.022606382,"height":0.014764565},"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 May 17:20","depth":11,"bounds":{"left":0.5008311,"top":0.717079,"width":0.020777926,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"bounds":{"left":0.5249335,"top":0.7186752,"width":0.008976064,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"bounds":{"left":0.53673536,"top":0.717079,"width":0.012799202,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.5505319,"top":0.7178771,"width":0.006150266,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"bounds":{"left":0.8784907,"top":0.7158819,"width":0.022606382,"height":0.014764565},"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 May 17:19","depth":11,"bounds":{"left":0.5008311,"top":0.7581804,"width":0.020279255,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"bounds":{"left":0.52443486,"top":0.75977653,"width":0.008976064,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"bounds":{"left":0.53607047,"top":0.7581804,"width":0.012965426,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.5500333,"top":0.7589784,"width":0.006150266,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"bounds":{"left":0.8784907,"top":0.7569832,"width":0.022606382,"height":0.014764565},"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 May 17:17","depth":11,"bounds":{"left":0.5008311,"top":0.7992817,"width":0.020113032,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"bounds":{"left":0.5242686,"top":0.80087787,"width":0.008976064,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"bounds":{"left":0.5359042,"top":0.7992817,"width":0.012799202,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.5497008,"top":0.8000798,"width":0.006150266,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"bounds":{"left":0.8784907,"top":0.7980846,"width":0.022606382,"height":0.014764565},"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 May 17:17","depth":11,"bounds":{"left":0.5008311,"top":0.84038305,"width":0.020113032,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"bounds":{"left":0.5242686,"top":0.84197927,"width":0.008976064,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"bounds":{"left":0.5359042,"top":0.84038305,"width":0.012799202,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.5497008,"top":0.84118116,"width":0.006150266,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"bounds":{"left":0.8784907,"top":0.83918595,"width":0.022606382,"height":0.014764565},"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"$","depth":11,"bounds":{"left":0.5008311,"top":0.8595371,"width":0.0026595744,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 17:17","depth":11,"bounds":{"left":0.5008311,"top":0.8970471,"width":0.020113032,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"bounds":{"left":0.5242686,"top":0.89864326,"width":0.008976064,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"bounds":{"left":0.5359042,"top":0.8970471,"width":0.012799202,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.5497008,"top":0.89784515,"width":0.006150266,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"bounds":{"left":0.8784907,"top":0.89584994,"width":0.022606382,"height":0.014764565},"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":";","depth":11,"bounds":{"left":0.5008311,"top":0.9162011,"width":0.0013297872,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 17:17","depth":11,"bounds":{"left":0.5008311,"top":0.9537111,"width":0.020113032,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"bounds":{"left":0.5242686,"top":0.95530725,"width":0.008976064,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"bounds":{"left":0.5359042,"top":0.9537111,"width":0.012799202,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.5497008,"top":0.9545092,"width":0.006150266,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"bounds":{"left":0.8784907,"top":0.952514,"width":0.022606382,"height":0.014764565},"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"=","depth":11,"bounds":{"left":0.5008311,"top":0.9728651,"width":0.0026595744,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 17:16","depth":11,"bounds":{"left":0.5008311,"top":1.0,"width":0.020279255,"height":-0.010375142},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"bounds":{"left":0.52443486,"top":1.0,"width":0.008976064,"height":-0.011971235},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"bounds":{"left":0.53607047,"top":1.0,"width":0.012965426,"height":-0.010375142},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.5500333,"top":1.0,"width":0.006150266,"height":-0.011173129},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"bounds":{"left":0.8784907,"top":1.0,"width":0.022606382,"height":-0.009177923},"on_screen":false,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":":","depth":11,"bounds":{"left":0.5008311,"top":1.0,"width":0.0013297872,"height":-0.029529095},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 17:16","depth":11,"bounds":{"left":0.5008311,"top":1.0,"width":0.020279255,"height":-0.06703913},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"bounds":{"left":0.52443486,"top":1.0,"width":0.008976064,"height":-0.068635225},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"bounds":{"left":0.53607047,"top":1.0,"width":0.012965426,"height":-0.06703913},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.5500333,"top":1.0,"width":0.006150266,"height":-0.06783724},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"bounds":{"left":0.8784907,"top":1.0,"width":0.022606382,"height":-0.06584203},"on_screen":false,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 May 17:15","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":false,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":".","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 17:15","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":false,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 May 17:14","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":false,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 May 17:14","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":false,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":".","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 17:10","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":false,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 May 17:09","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":false,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 May 17:08","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":false,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 May 17:07","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":false,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 May 14:13","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":false,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"secondly","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 10:58","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"clipboard","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":false,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"...search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"secondly","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019dffc4-4 (truncated...)","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 10:41","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
6919465101728380891
|
6266311007377799464
|
click
|
accessibility
|
NULL
|
New Tab
New Tab
Screenpipe — Archive
Screenpipe — New Tab
New Tab
Screenpipe — Archive
Screenpipe — Archive
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe [archive.db · 12323.6MB]
Screenpipe
[archive.db · 12323.6MB]
Activity
Search
Audio
Work Report
Timetable
AI Summary
Date
07
/
05
/
2026
Calendar
SECONDLY
Search
AND also
second required term — both must appear in same result (optional)
Source
App
Date
dd
/
mm
/
yyyy
Calendar
(blank = all dates)
From
--
:
--
To
--
:
--
Only apps
any app (blank = all)
▾
Skip apps
none skipped
▾
FTS tip: single words work best · "exact phrase" · term1 OR term2 · use AND also for required second term · times are in your local timezone · click any result to expand
49 results
▶ video
7 May 19:25
Screen
PhpStorm
/ faVsco.js – Client.php
⏱ Timeline
...true) ??
:SpolicyName = $body
'policyName'
?? Sbody
'policy'
?? null:Map pollcy names to retry delaysif (SpolicvName === 'TEN
SECONDLY
_ROLLING' |I SpolicvName === 'ten
secondly
rolling') {
… (click to expand)
▶ video
7 May 19:10
Screen
PhpStorm
/ faVsco.js – Client.php
⏱ Timeline
...true) ??
:Snolievlane = Sbod/LUpoltiev/lane:1 22 Shody
LnolieyL1L.22 п11rao nolicy names to retry delav1f SpoLicvName ==='TEN
SECONDLY
ROLLING' |I SpolicvName === 'ten
secondly
rolling') {Le
… (click to expand)
7 May 17:24
Typed
Firefox
text
⏱ Timeline
.
7 May 17:23
Typed
Firefox
text
⏱ Timeline
7 May 17:22
Typed
Firefox
text
⏱ Timeline
.
7 May 17:22
Typed
Firefox
text
⏱ Timeline
'
7 May 17:21
Typed
Firefox
text
⏱ Timeline
7 May 17:20
Typed
Firefox
text
⏱ Timeline
7 May 17:19
Typed
Firefox
text
⏱ Timeline
7 May 17:17
Typed
Firefox
text
⏱ Timeline
7 May 17:17
Typed
Firefox
text
⏱ Timeline
$
7 May 17:17
Typed
Firefox
text
⏱ Timeline
;
7 May 17:17
Typed
Firefox
text
⏱ Timeline
=
7 May 17:16
Typed
Firefox
text
⏱ Timeline
:
7 May 17:16
Typed
Firefox
text
⏱ Timeline
7 May 17:15
Typed
Firefox
text
⏱ Timeline
.
7 May 17:15
Typed
Firefox
text
⏱ Timeline
7 May 17:14
Typed
Firefox
text
⏱ Timeline
7 May 17:14
Typed
Firefox
text
⏱ Timeline
.
7 May 17:10
Typed
Firefox
text
⏱ Timeline
7 May 17:09
Typed
Firefox
text
⏱ Timeline
7 May 17:08
Typed
Firefox
text
⏱ Timeline
7 May 17:07
Typed
Firefox
text
⏱ Timeline
7 May 14:13
Typed
Claude
text
⏱ Timeline
secondly
7 May 10:58
Typed
clipboard
⏱ Timeline
...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...)
7 May 10:41
Typed...
|
17473
|
NULL
|
NULL
|
NULL
|
|
17490
|
772
|
40
|
2026-05-11T10:24:26.896448+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778495066896_m1.jpg...
|
Firefox
|
Screenpipe — Archive — Personal
|
True
|
app.screenpipe.lakylak.xyz
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
New Tab
New Tab
Screenpipe — Archive
Screenpipe — New Tab
New Tab
Screenpipe — Archive
Screenpipe — Archive
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe [archive.db · 12323.6MB]
Screenpipe
[archive.db · 12323.6MB]
Activity
Search
Audio
Work Report
Timetable
AI Summary
Date
07
/
05
/
2026
Calendar
SECONDLY
Search
AND also
second required term — both must appear in same result (optional)
Source
App
Date
dd
/
mm
/
yyyy
Calendar
(blank = all dates)
From
--
:
--
To
--
:
--
Only apps
any app (blank = all)
▾
Skip apps
none skipped
▾
FTS tip: single words work best · "exact phrase" · term1 OR term2 · use AND also for required second term · times are in your local timezone · click any result to expand
49 results
▶ video
7 May 19:25
Screen
PhpStorm
/ faVsco.js – Client.php
⏱ Timeline
...true) ??
:SpolicyName = $body
'policyName'
?? Sbody
'policy'
?? null:Map pollcy names to retry delaysif (SpolicvName === 'TEN
SECONDLY
_ROLLING' |I SpolicvName === 'ten
secondly
rolling') {
… (click to expand)
▶ video
7 May 19:10
Screen
PhpStorm
/ faVsco.js – Client.php
⏱ Timeline
...true) ??
:Snolievlane = Sbod/LUpoltiev/lane:1 22 Shody
LnolieyL1L.22 п11rao nolicy names to retry delav1f SpoLicvName ==='TEN
SECONDLY
ROLLING' |I SpolicvName === 'ten
secondly
rolling') {Le
… (click to expand)
7 May 17:24
Typed
Firefox
text
⏱ Timeline
.
7 May 17:23
Typed
Firefox
text
⏱ Timeline
7 May 17:22
Typed
Firefox
text
⏱ Timeline
.
7 May 17:22
Typed
Firefox
text
⏱ Timeline
'
7 May 17:21
Typed
Firefox
text
⏱ Timeline
7 May 17:20
Typed
Firefox
text
⏱ Timeline
7 May 17:19
Typed
Firefox
text
⏱ Timeline
7 May 17:17
Typed
Firefox
text
⏱ Timeline
7 May 17:17
Typed
Firefox
text
⏱ Timeline
$
7 May 17:17
Typed
Firefox
text
⏱ Timeline
;
7 May 17:17
Typed
Firefox
text
⏱ Timeline
=
7 May 17:16
Typed
Firefox
text
⏱ Timeline
:
7 May 17:16
Typed
Firefox
text
⏱ Timeline
7 May 17:15
Typed
Firefox
text
⏱ Timeline
.
7 May 17:15
Typed
Firefox
text
⏱ Timeline
7 May 17:14...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe — Archive","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.043402776,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.06631944,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.08958333,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.112847224,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"bounds":{"left":0.13611111,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Screenpipe [archive.db · 12323.6MB]","depth":7,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Screenpipe","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[archive.db · 12323.6MB]","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Activity","depth":7,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search","depth":7,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Audio","depth":7,"on_screen":true,"help_text":"No audio data in this database","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Work Report","depth":7,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Timetable","depth":7,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Summary","depth":7,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Date","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"07","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"05","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Calendar","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"SECONDLY","depth":8,"on_screen":true,"value":"SECONDLY","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"AND also","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"second required term — both must appear in same result (optional)","depth":8,"on_screen":true,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Source","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"App","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dd","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"mm","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"yyyy","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Calendar","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"(blank = all dates)","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"From","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"To","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Only apps","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"any app (blank = all)","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▾","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Skip apps","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"none skipped","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▾","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FTS tip: single words work best · \"exact phrase\" · term1 OR term2 · use AND also for required second term · times are in your local timezone · click any result to expand","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"49 results","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▶ video","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 19:25","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Screen","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PhpStorm","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/ faVsco.js – Client.php","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"...true) ??","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":SpolicyName = $body","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'policyName'","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"?? Sbody","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'policy'","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"?? null:Map pollcy names to retry delaysif (SpolicvName === 'TEN","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SECONDLY","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"_ROLLING' |I SpolicvName === 'ten","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"secondly","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"rolling') {","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"… (click to expand)","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▶ video","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 19:10","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Screen","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PhpStorm","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/ faVsco.js – Client.php","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"...true) ??","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":Snolievlane = Sbod/LUpoltiev/lane:1 22 Shody","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"LnolieyL1L.22 п11rao nolicy names to retry delav1f SpoLicvName ==='TEN","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SECONDLY","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ROLLING' |I SpolicvName === 'ten","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"secondly","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"rolling') {Le","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"… (click to expand)","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 17:24","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"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":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":".","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 17:23","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"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":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 May 17:22","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"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":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":".","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 17:22","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"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":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"'","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 17:21","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"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":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 May 17:20","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"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":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 May 17:19","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"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":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 May 17:17","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"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":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 May 17:17","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"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":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"$","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 17:17","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"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":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":";","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 17:17","depth":11,"bounds":{"left":0.48159721,"top":0.0,"width":0.042013887,"height":0.015},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"bounds":{"left":0.53055555,"top":0.0,"width":0.01875,"height":0.012222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"bounds":{"left":0.5548611,"top":0.0,"width":0.02673611,"height":0.015},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.58368057,"top":0.0,"width":0.012847222,"height":0.013888889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":true,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"=","depth":11,"bounds":{"left":0.48159721,"top":0.0,"width":0.0055555557,"height":0.017777778},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 17:16","depth":11,"bounds":{"left":0.48159721,"top":0.014444444,"width":0.04236111,"height":0.015},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"bounds":{"left":0.5309028,"top":0.016666668,"width":0.01875,"height":0.012222222},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"bounds":{"left":0.5552083,"top":0.014444444,"width":0.027083334,"height":0.015},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.584375,"top":0.015555556,"width":0.012847222,"height":0.013888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":false,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":":","depth":11,"bounds":{"left":0.48159721,"top":0.04111111,"width":0.0027777778,"height":0.017777778},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 17:16","depth":11,"bounds":{"left":0.48159721,"top":0.093333334,"width":0.04236111,"height":0.015},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"bounds":{"left":0.5309028,"top":0.09555556,"width":0.01875,"height":0.012222222},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"bounds":{"left":0.5552083,"top":0.093333334,"width":0.027083334,"height":0.015},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.584375,"top":0.094444446,"width":0.012847222,"height":0.013888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":false,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 May 17:15","depth":11,"bounds":{"left":0.48159721,"top":0.15055555,"width":0.04236111,"height":0.015},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"bounds":{"left":0.5309028,"top":0.15277778,"width":0.01875,"height":0.012222222},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"bounds":{"left":0.5552083,"top":0.15055555,"width":0.02673611,"height":0.015},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.584375,"top":0.15166667,"width":0.0125,"height":0.013888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":false,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":".","depth":11,"bounds":{"left":0.48159721,"top":0.17722222,"width":0.0027777778,"height":0.017777778},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 17:15","depth":11,"bounds":{"left":0.48159721,"top":0.22944444,"width":0.04236111,"height":0.015},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Typed","depth":11,"bounds":{"left":0.5309028,"top":0.23166667,"width":0.01875,"height":0.012222222},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":12,"bounds":{"left":0.5552083,"top":0.22944444,"width":0.02673611,"height":0.015},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"text","depth":11,"bounds":{"left":0.584375,"top":0.23055555,"width":0.0125,"height":0.013888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏱ Timeline","depth":10,"on_screen":false,"help_text":"Open in Timetable","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 May 17:14","depth":11,"bounds":{"left":0.48159721,"top":0.28666666,"width":0.04236111,"height":0.015},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
2976223957839529050
|
8428041027538893097
|
click
|
accessibility
|
NULL
|
New Tab
New Tab
Screenpipe — Archive
Screenpipe — New Tab
New Tab
Screenpipe — Archive
Screenpipe — Archive
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe [archive.db · 12323.6MB]
Screenpipe
[archive.db · 12323.6MB]
Activity
Search
Audio
Work Report
Timetable
AI Summary
Date
07
/
05
/
2026
Calendar
SECONDLY
Search
AND also
second required term — both must appear in same result (optional)
Source
App
Date
dd
/
mm
/
yyyy
Calendar
(blank = all dates)
From
--
:
--
To
--
:
--
Only apps
any app (blank = all)
▾
Skip apps
none skipped
▾
FTS tip: single words work best · "exact phrase" · term1 OR term2 · use AND also for required second term · times are in your local timezone · click any result to expand
49 results
▶ video
7 May 19:25
Screen
PhpStorm
/ faVsco.js – Client.php
⏱ Timeline
...true) ??
:SpolicyName = $body
'policyName'
?? Sbody
'policy'
?? null:Map pollcy names to retry delaysif (SpolicvName === 'TEN
SECONDLY
_ROLLING' |I SpolicvName === 'ten
secondly
rolling') {
… (click to expand)
▶ video
7 May 19:10
Screen
PhpStorm
/ faVsco.js – Client.php
⏱ Timeline
...true) ??
:Snolievlane = Sbod/LUpoltiev/lane:1 22 Shody
LnolieyL1L.22 п11rao nolicy names to retry delav1f SpoLicvName ==='TEN
SECONDLY
ROLLING' |I SpolicvName === 'ten
secondly
rolling') {Le
… (click to expand)
7 May 17:24
Typed
Firefox
text
⏱ Timeline
.
7 May 17:23
Typed
Firefox
text
⏱ Timeline
7 May 17:22
Typed
Firefox
text
⏱ Timeline
.
7 May 17:22
Typed
Firefox
text
⏱ Timeline
'
7 May 17:21
Typed
Firefox
text
⏱ Timeline
7 May 17:20
Typed
Firefox
text
⏱ Timeline
7 May 17:19
Typed
Firefox
text
⏱ Timeline
7 May 17:17
Typed
Firefox
text
⏱ Timeline
7 May 17:17
Typed
Firefox
text
⏱ Timeline
$
7 May 17:17
Typed
Firefox
text
⏱ Timeline
;
7 May 17:17
Typed
Firefox
text
⏱ Timeline
=
7 May 17:16
Typed
Firefox
text
⏱ Timeline
:
7 May 17:16
Typed
Firefox
text
⏱ Timeline
7 May 17:15
Typed
Firefox
text
⏱ Timeline
.
7 May 17:15
Typed
Firefox
text
⏱ Timeline
7 May 17:14...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
17708
|
777
|
40
|
2026-05-11T10:30:04.432876+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778495404432_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
21:30
7 May 15:32 · PhpStorm / faVsco.js – OpportunitySyncTrait.php
⏮ 30s
◀ 10s
▶ Play
10s ▶
30s ⏭
15:32
iTerm2
Firefox
CleanShot X
Finder
QuickTime Player
PhpStorm
Music
Control Centre
Claude
Slack
Alfred
Raycast
System Information...
|
[{"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"},{"role":"AXStaticText","text":"21:30","depth":13,"bounds":{"left":0.8997673,"top":0.21947326,"width":0.008144947,"height":0.008778931},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7 May 15:32 · PhpStorm / faVsco.js – OpportunitySyncTrait.php","depth":10,"bounds":{"left":0.49817154,"top":0.2661612,"width":0.11801862,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏮ 30s","depth":9,"bounds":{"left":0.49883643,"top":0.7186752,"width":0.023936171,"height":0.02434158},"on_screen":true,"help_text":"Ctrl+←","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"◀ 10s","depth":9,"bounds":{"left":0.52543217,"top":0.71907425,"width":0.02244016,"height":0.023942538},"on_screen":true,"help_text":"←","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"▶ Play","depth":9,"bounds":{"left":0.5505319,"top":0.71907425,"width":0.027925532,"height":0.023942538},"on_screen":true,"help_text":"Space","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXButton","text":"10s ▶","depth":9,"bounds":{"left":0.58111703,"top":0.71907425,"width":0.022273935,"height":0.023942538},"on_screen":true,"help_text":"→","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"30s ⏭","depth":9,"bounds":{"left":0.60605055,"top":0.7186752,"width":0.024102394,"height":0.02434158},"on_screen":true,"help_text":"Ctrl+→","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"15:32","depth":10,"bounds":{"left":0.89943486,"top":0.7254589,"width":0.009640957,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"iTerm2","depth":9,"bounds":{"left":0.49950132,"top":0.7609737,"width":0.011801862,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":9,"bounds":{"left":0.51961434,"top":0.7609737,"width":0.011801862,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CleanShot X","depth":9,"bounds":{"left":0.5397274,"top":0.7609737,"width":0.021609042,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Finder","depth":9,"bounds":{"left":0.5696476,"top":0.7609737,"width":0.010970744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"QuickTime Player","depth":9,"bounds":{"left":0.58892953,"top":0.7609737,"width":0.030086435,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PhpStorm","depth":9,"bounds":{"left":0.62732714,"top":0.7609737,"width":0.017287234,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Music","depth":9,"bounds":{"left":0.65292555,"top":0.7609737,"width":0.010305851,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Control Centre","depth":9,"bounds":{"left":0.6715425,"top":0.7609737,"width":0.025598405,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude","depth":9,"bounds":{"left":0.70545214,"top":0.7609737,"width":0.012134309,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slack","depth":9,"bounds":{"left":0.7258976,"top":0.7609737,"width":0.009474734,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Alfred","depth":9,"bounds":{"left":0.7436835,"top":0.7609737,"width":0.010472074,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Raycast","depth":9,"bounds":{"left":0.7624667,"top":0.7609737,"width":0.013630319,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"System Information","depth":9,"bounds":{"left":0.7844083,"top":0.7609737,"width":0.033909574,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
1621335301738669243
|
2864771129291932573
|
visual_change
|
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
21:30
7 May 15:32 · PhpStorm / faVsco.js – OpportunitySyncTrait.php
⏮ 30s
◀ 10s
▶ Play
10s ▶
30s ⏭
15:32
iTerm2
Firefox
CleanShot X
Finder
QuickTime Player
PhpStorm
Music
Control Centre
Claude
Slack
Alfred
Raycast
System Information...
|
17707
|
NULL
|
NULL
|
NULL
|
|
17756
|
776
|
40
|
2026-05-11T10:32:00.120031+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778495520120_m1.jpg...
|
PhpStorm
|
faVsco.js – Kernel.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...
|
[{"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}]...
|
5685266402682420683
|
-8926130836387591936
|
click
|
hybrid
|
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
SlackFileEditViewGoHistoryWindowHelpDOCKERO ₴1DEV (docker)Last login: Sun May 10 21:10:26 on ttys013₴2APP (-zsh)883Poetry could not find a pyproject.toml file in /Users/lukas or its parentsPoetry could not find a pyproject.toml file in /Users/lukas or its parentslukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ l-zshHomeDMsActivityFilesLater..•MoreallEDJiminny ...clusticclllus+ More unreads## jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of_jimi...• Direct messages®. Aneliya Angelova. Galya DimitrovaP Petko Kashinskiã. Stefka Stoyanova€. Vasil Vasilev 0. Nikolay IvanovAneliya Angelova, ...2 Stoyan Tanev•. Ves8. Lukas Kovalik y...::: AppsToastJira CloudGoogle Cale...Support Daily - in 1h 29 m100% <78• Mon 11 May 13:31:59Describe what you are looking forAneliya Angelova6 0MessagesAdd canvasO Files+чuле да сс мордиnс anо viма approveTuesday, April 28th~Lukas Kova..те са някави flanky че при мен минават, ще гиоправяза деплой обаче не знамAneliya Angelova 5:14 PMзащоLukas Kovalik 5:15 PMами дали ще усепя да гледамAneliya Angelova 5:16 PMи за двете ли говоришLukas Kovalik 5:16 PMами ще го деплойна но ако нещо грьмнеAneliya Angelova 5:17 PMаа разбрахтеГаля каза че не се използва фичьраи няма проблем да грьмнеToday ~NewAneliya Angelova 1:24 PMЛукаш за Hubspot за синковете вече се използватази команда нали?crm: sync-hubspot-objectsMessage Aneliya Angelova..•...
|
17754
|
NULL
|
NULL
|
NULL
|
|
17923
|
780
|
40
|
2026-05-11T10:41:39.079423+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778496099079_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
3
68
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
{
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$e ' . PHP_EOL . print_r($e, true));
return 5;
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);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All...
|
[{"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":"3","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"68","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 \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$e ' . PHP_EOL . print_r($e, true));\n return 5;\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 \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$e ' . PHP_EOL . print_r($e, true));\n return 5;\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":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"19","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","depth":4,"on_screen":true,"value":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
7623778648713633268
|
6378618611371477092
|
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
3
68
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
{
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$e ' . PHP_EOL . print_r($e, true));
return 5;
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);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
17927
|
781
|
40
|
2026-05-11T10:41:59.243647+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778496119243_m2.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest
Run 'HandleHubspotRateLimitTest'
Debug 'HandleHubspotRateLimitTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
68
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
{
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$e ' . PHP_EOL . print_r($e, true));
return 5;
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);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}...
|
[{"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":"3","depth":4,"bounds":{"left":0.5515292,"top":0.15003991,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"68","depth":4,"bounds":{"left":0.56150264,"top":0.15003991,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"3","depth":4,"bounds":{"left":0.5738032,"top":0.15003991,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.5834442,"top":0.14844373,"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.59075797,"top":0.14844373,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\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 \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$e ' . PHP_EOL . print_r($e, true));\n return 5;\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 \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$e ' . PHP_EOL . print_r($e, true));\n return 5;\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":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"19","depth":4,"bounds":{"left":0.96276593,"top":0.07581804,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.9740692,"top":0.074221864,"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.98138297,"top":0.074221864,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","depth":4,"bounds":{"left":0.61702126,"top":0.0726257,"width":0.38297874,"height":0.9066241},"on_screen":true,"value":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-1006337435740056067
|
6378618611371477092
|
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
3
68
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
{
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$e ' . PHP_EOL . print_r($e, true));
return 5;
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);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
18028
|
783
|
40
|
2026-05-11T10:45:55.556084+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778496355556_m2.jpg...
|
Notion Calendar
|
NULL
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
ClaudtVIeWWindow•• •O, Chat*= Cowork+ New chatÔ Pr ClaudtVIeWWindow•• •O, Chat*= Cowork+ New chatÔ Projectso0 Arutacts₴ CustomizeBulgarian citizenship application proces:Dawarich location tracking projectKecentsHubspot Badkequest headers debuggin.Screenpipe svnc script tailing after receiMonthly expense trackingExporting transaction data from NotionHow much have I spent for groc…April 2026 spending by categoryCode dift reviewHubSpot rate limit imolementation strateScreenpipe retention policy code locaticViewing retention policy in screenpipeClean snot x video recording terminaticHubSpot rate limit handling with executeUntitledg Screen pipe. Is there ability..SMB mount access inconsistency betwea What is the hect switch Icanrermission deniea on screenpipe volumeScreenpipe sync database attachment eLast swimming outing with DanDefinition of incarceratedCode diff review vt/Service.onp"suppont Dally • In 1h 1om100% L2• Mon 11 May 13:45:55« console (PROD]* console (EUl& console (STAGINGIw.19Aounerwise une aererea draneh wil nerany never execure and tne cleanuo comment decomes aSmaller stuft:• Throwable became Throwable -makesure use Throwable: was added at the top ofthe fle, otherwise it'll fatal on the catch.• The block comment now lives inside the if (isDeleted) branch, which reads fine and isgenuinely better documentation than the old code had. Nice touch• The try/catch only wraps the update path, same as before — consistent, not aregressionbility win• Gearch chats and proiectsore approving -nimbortant soth• Health• How repairs⅝ Paramedie@ Hubspot BadReguest headers debuggingPast houvou think aboutScreenpipe sync script failing after recent migrationsLeaknhutt the• Monthly expense trackingYesterdayand manuallv unsetc@ Exporting transaction data from Notion to finance hubYesterday• • How much have I spent for groc….Past wee!ously instantiatesToUpdate and IDstoc April 2026 spending by categoryPast weel@ HubSpot rate limit implementation strategyPast weel@ Screenpine retention policy code locationPast weel• Viewing retention policy in screenpipePast monthMostlv thoughtful but the framing on (A) is wrong, and there's a real point being made on B)that deserves more weight than the others. Going through them:**A - Infinite Accumulation: overstated and misattributed to this PR.** Look back at the oldcode: documentst ou pdate'and'documentstoDelete are captured by use(...) in thechunk callback and accumulated across all chunks. then returned. The new code does theevaet came thino Whatever the accumuiation hehavior of this method is it'cidentical heforeandafter the diff. The reviewer is calling out a pre-existing architectural choice as if therefactor introduced it. The bit about "manually unsetting " $entityModel'" also looks like it'sreferring to code that isn't actuallv in the diff —'nursor()' drons references between vieldsautomatically: you don't need an explicit' unse V o either the reviewer is describing codethat exists elsewhere in the file/method. or thev're imagining it. If the accumulation isWrite a message…Opus 4.7 Adaptive© PaginationConfig.phpA3A70 V3 /|_175288= custom.log Xlaravel.log4 SF [jiminny@localhost]& HS_local [jiminny@localhost][2026-05-07 14:21:15] local.INF0: [Hubspot] DEBUG Getting headers {"neaders".?"Date":["Thu,07 May 2026 14:21:15 GMT"],"Content-Type":["application/json;charset=utf-8"]."Transfer-Encoding": ["chunked"],"conneccion". Keep-alive"n"CF-Ray" : ["9f80deb8db60dc3a-SOF"],"CF-Cache-Status":"DYNAMIC"]"Strict-Transport-Secur1ty":"max-aqe=31536000* 1ncLudesubDomains: preload")accept-encoding"],"access-control-allow-credentials": "false")"server-timing": ["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",cfn:desc="9-80de8ercodc3a-TAD"'"x-content-type-options": ["nosniff"]."x-hubsoot-correlation-id":"019e02d0-6fd8-7812-bdba-885b7ccb3ee3"]"Set-Cookie":["__cf_bm=S1UrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-r1.ZggtDKxTge5zr8_2gbBfW100.ufZEXDZyHz2mBUFdzdo2gTHEs0,07-May-26 14:51:15 GMT; domain=.hubapi.com; Http0nly; Secure; SameSite=None"],"Renont-To".f","endnoints".?\"url\":\"https:|V/\V/a.nel.cloudflare.com/\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZLzoYdxI%2BIxVpHmsKn30%2BKVA3mFIJ2m7YRECDGS\"group\":\"cf-nel\",\"max_age\":604800}"],"success_fraction\":0.01,"nenont to":"cf-nel"\"max_age\":604800}"],"Server": ["cloudflare"]}} {"correlation id":"95236535-ec98-4541-b92a-adfa73b69eab" ."trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}lK Lukas. ProCiaudo ic Aland can mako mictakac Plence double-chock recnoncodW Windsurf Teams 20-17UTF.Rfo 4 spaces 0...
|
NULL
|
-3771738662876001381
|
NULL
|
visual_change
|
ocr
|
NULL
|
ClaudtVIeWWindow•• •O, Chat*= Cowork+ New chatÔ Pr ClaudtVIeWWindow•• •O, Chat*= Cowork+ New chatÔ Projectso0 Arutacts₴ CustomizeBulgarian citizenship application proces:Dawarich location tracking projectKecentsHubspot Badkequest headers debuggin.Screenpipe svnc script tailing after receiMonthly expense trackingExporting transaction data from NotionHow much have I spent for groc…April 2026 spending by categoryCode dift reviewHubSpot rate limit imolementation strateScreenpipe retention policy code locaticViewing retention policy in screenpipeClean snot x video recording terminaticHubSpot rate limit handling with executeUntitledg Screen pipe. Is there ability..SMB mount access inconsistency betwea What is the hect switch Icanrermission deniea on screenpipe volumeScreenpipe sync database attachment eLast swimming outing with DanDefinition of incarceratedCode diff review vt/Service.onp"suppont Dally • In 1h 1om100% L2• Mon 11 May 13:45:55« console (PROD]* console (EUl& console (STAGINGIw.19Aounerwise une aererea draneh wil nerany never execure and tne cleanuo comment decomes aSmaller stuft:• Throwable became Throwable -makesure use Throwable: was added at the top ofthe fle, otherwise it'll fatal on the catch.• The block comment now lives inside the if (isDeleted) branch, which reads fine and isgenuinely better documentation than the old code had. Nice touch• The try/catch only wraps the update path, same as before — consistent, not aregressionbility win• Gearch chats and proiectsore approving -nimbortant soth• Health• How repairs⅝ Paramedie@ Hubspot BadReguest headers debuggingPast houvou think aboutScreenpipe sync script failing after recent migrationsLeaknhutt the• Monthly expense trackingYesterdayand manuallv unsetc@ Exporting transaction data from Notion to finance hubYesterday• • How much have I spent for groc….Past wee!ously instantiatesToUpdate and IDstoc April 2026 spending by categoryPast weel@ HubSpot rate limit implementation strategyPast weel@ Screenpine retention policy code locationPast weel• Viewing retention policy in screenpipePast monthMostlv thoughtful but the framing on (A) is wrong, and there's a real point being made on B)that deserves more weight than the others. Going through them:**A - Infinite Accumulation: overstated and misattributed to this PR.** Look back at the oldcode: documentst ou pdate'and'documentstoDelete are captured by use(...) in thechunk callback and accumulated across all chunks. then returned. The new code does theevaet came thino Whatever the accumuiation hehavior of this method is it'cidentical heforeandafter the diff. The reviewer is calling out a pre-existing architectural choice as if therefactor introduced it. The bit about "manually unsetting " $entityModel'" also looks like it'sreferring to code that isn't actuallv in the diff —'nursor()' drons references between vieldsautomatically: you don't need an explicit' unse V o either the reviewer is describing codethat exists elsewhere in the file/method. or thev're imagining it. If the accumulation isWrite a message…Opus 4.7 Adaptive© PaginationConfig.phpA3A70 V3 /|_175288= custom.log Xlaravel.log4 SF [jiminny@localhost]& HS_local [jiminny@localhost][2026-05-07 14:21:15] local.INF0: [Hubspot] DEBUG Getting headers {"neaders".?"Date":["Thu,07 May 2026 14:21:15 GMT"],"Content-Type":["application/json;charset=utf-8"]."Transfer-Encoding": ["chunked"],"conneccion". Keep-alive"n"CF-Ray" : ["9f80deb8db60dc3a-SOF"],"CF-Cache-Status":"DYNAMIC"]"Strict-Transport-Secur1ty":"max-aqe=31536000* 1ncLudesubDomains: preload")accept-encoding"],"access-control-allow-credentials": "false")"server-timing": ["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",cfn:desc="9-80de8ercodc3a-TAD"'"x-content-type-options": ["nosniff"]."x-hubsoot-correlation-id":"019e02d0-6fd8-7812-bdba-885b7ccb3ee3"]"Set-Cookie":["__cf_bm=S1UrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-r1.ZggtDKxTge5zr8_2gbBfW100.ufZEXDZyHz2mBUFdzdo2gTHEs0,07-May-26 14:51:15 GMT; domain=.hubapi.com; Http0nly; Secure; SameSite=None"],"Renont-To".f","endnoints".?\"url\":\"https:|V/\V/a.nel.cloudflare.com/\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZLzoYdxI%2BIxVpHmsKn30%2BKVA3mFIJ2m7YRECDGS\"group\":\"cf-nel\",\"max_age\":604800}"],"success_fraction\":0.01,"nenont to":"cf-nel"\"max_age\":604800}"],"Server": ["cloudflare"]}} {"correlation id":"95236535-ec98-4541-b92a-adfa73b69eab" ."trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}lK Lukas. ProCiaudo ic Aland can mako mictakac Plence double-chock recnoncodW Windsurf Teams 20-17UTF.Rfo 4 spaces 0...
|
18026
|
NULL
|
NULL
|
NULL
|
|
18035
|
782
|
40
|
2026-05-11T10:46:11.204776+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778496371204_m1.jpg...
|
Notion Calendar
|
NULL
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV (docker)$2APP (-zsh)883viewsjiminny-worker-processing-2:jiminny-worker-processing-2_00: stoppedjiminny-worker-processing-3:jiminny-worker-processing-3_00: stoppedjiminny-worker-processing-4: jiminny-worker-processing-4_00: stoppedJiminny-worker-processing-5:j1minny-worker-processing-5_00:jiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: stoppedworker-analytics:worker-analytics_00: stoppedworker-conferences:worker-conferences_00: stoppedworker-crm-update:worker-crm-update_00: stoppedworker-download:worker-download_00: stoppedworker-emails:worker-emails_00: stoppedworker-nudges:worker-nudges_00: stoppedworker:worker_00: stoppedworker-audio:worker-audio_00: stoppedworker-calendar:worker-calendar_00: stoppedworker-crm-sync:worker-crm-sync_00: stoppedartisan-schedule:artisan-schedule_00: stoppedworker-es-update:worker-es-update_00: stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedartisan-schedule:artisan-schedule_00: startedjiminny-worker-processing-1:jiminny-worker-processing-1_00: startedjiminny-worker-processing-2:jiminny-worker-processing-2_00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00:jiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00: startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00: startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00: startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny#php artisan jiminny:debugDispatching 100 MatchActivityCrmData jobs (portal=2)Done. Watch logs and run jiminny:debug observeRateLimit to inspect cache state.root@docker_lamp_1:/home/jiminny# php artisan jiminny:debugDispatching 100 MatchActivityCrmData jobs (portal=2)Done. Watch logs and run jiminny:debug observeRateLimit to inspect cache state.root@docker_lamp_1:/home/jiminny# ]DEV (d)-zshHomeDMsActivityFilesLater...MorelallSupport Daily • in 1h 14 m100% <78• Mon 11 May 13:46:10ED→Describe what you are looking forJiminny ...# contusion-clinic# curiosity_lab# engineering# general# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...ToastHomeMessages^ Direct messages®. Aneliya Angelova®. Galya Dimitrova& Petko Kashinski&. Stefka StoyanovaVasil Vasilev OlC. Nikolay IvanovAneliya Angelova, ...Stoyan Tanev®. VesE Lukas Kovalik y... 0AboutiminnyFriday, May 8th ~Added by Toast for GitHubToday ~Toast APP10:00 AMReviewapp#12059 Jy 20820 es reindexstream model hydration2 days old • 12 files changed •@Vasil VasilevAdded by Toast for GitHubResolve Conflictsapp#11443 Test hublets latency5 months old • 20 files changed#11327 JY-19501 webhookbased opportunity syncShow moreAdded by Toast for GitHubNeeds Loveapp#12024 JY-20773 fix user pilottracking ofr automated reportgenerated12 days old • 1 file changedE:: AppsMessage ToastJira CloudToast+AaConala CalaNew...
|
NULL
|
7456591756315406747
|
NULL
|
click
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV (docker)$2APP (-zsh)883viewsjiminny-worker-processing-2:jiminny-worker-processing-2_00: stoppedjiminny-worker-processing-3:jiminny-worker-processing-3_00: stoppedjiminny-worker-processing-4: jiminny-worker-processing-4_00: stoppedJiminny-worker-processing-5:j1minny-worker-processing-5_00:jiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: stoppedworker-analytics:worker-analytics_00: stoppedworker-conferences:worker-conferences_00: stoppedworker-crm-update:worker-crm-update_00: stoppedworker-download:worker-download_00: stoppedworker-emails:worker-emails_00: stoppedworker-nudges:worker-nudges_00: stoppedworker:worker_00: stoppedworker-audio:worker-audio_00: stoppedworker-calendar:worker-calendar_00: stoppedworker-crm-sync:worker-crm-sync_00: stoppedartisan-schedule:artisan-schedule_00: stoppedworker-es-update:worker-es-update_00: stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedartisan-schedule:artisan-schedule_00: startedjiminny-worker-processing-1:jiminny-worker-processing-1_00: startedjiminny-worker-processing-2:jiminny-worker-processing-2_00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00:jiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00: startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00: startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00: startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny#php artisan jiminny:debugDispatching 100 MatchActivityCrmData jobs (portal=2)Done. Watch logs and run jiminny:debug observeRateLimit to inspect cache state.root@docker_lamp_1:/home/jiminny# php artisan jiminny:debugDispatching 100 MatchActivityCrmData jobs (portal=2)Done. Watch logs and run jiminny:debug observeRateLimit to inspect cache state.root@docker_lamp_1:/home/jiminny# ]DEV (d)-zshHomeDMsActivityFilesLater...MorelallSupport Daily • in 1h 14 m100% <78• Mon 11 May 13:46:10ED→Describe what you are looking forJiminny ...# contusion-clinic# curiosity_lab# engineering# general# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...ToastHomeMessages^ Direct messages®. Aneliya Angelova®. Galya Dimitrova& Petko Kashinski&. Stefka StoyanovaVasil Vasilev OlC. Nikolay IvanovAneliya Angelova, ...Stoyan Tanev®. VesE Lukas Kovalik y... 0AboutiminnyFriday, May 8th ~Added by Toast for GitHubToday ~Toast APP10:00 AMReviewapp#12059 Jy 20820 es reindexstream model hydration2 days old • 12 files changed •@Vasil VasilevAdded by Toast for GitHubResolve Conflictsapp#11443 Test hublets latency5 months old • 20 files changed#11327 JY-19501 webhookbased opportunity syncShow moreAdded by Toast for GitHubNeeds Loveapp#12024 JY-20773 fix user pilottracking ofr automated reportgenerated12 days old • 1 file changedE:: AppsMessage ToastJira CloudToast+AaConala CalaNew...
|
18032
|
NULL
|
NULL
|
NULL
|
|
18267
|
791
|
40
|
2026-05-11T11:07:29.817987+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778497649817_m2.jpg...
|
PhpStorm
|
faVsco.js – HS_local [jiminny@localhost]
|
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
5
133
11
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\Crm\Delete\VerifyActivityCrmTaskJob;
use Jiminny\Jobs\Crm\MatchActivityCrmData;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
// Choose ONE of the following to run, then comment out the others.
// 1) Dispatch a storm of MatchActivityCrmData jobs against team 2
$this->simulateMatchActivityStorm(teamId: 2, count: 100);
// 2) Dispatch a storm of VerifyActivityCrmTaskJob jobs (simulates DeleteCrmEntityTrait fan-out)
// $this->simulateVerifyTaskStorm(teamId: 2, count: 100);
// 3) Inspect Redis circuit-breaker state for the team's HubSpot portal
// $this->observeRateLimitCache(teamId: 2);
// 4) Make 3 synchronous matchByName calls (foreground, hits API directly)
// $this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 3; $i++) {
// if ($i % 25 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
// }
// $crmService->syncOpportunity('374720564');
$crmService->matchByName('Robot');
}
}
private function simulateMatchActivityStorm(int $teamId = 2, int $count = 100): void
{
$team = Team::find($teamId);
$config = $team->getCrmConfiguration();
$activities = Activity::query()
->where('crm_configuration_id', $config->getId())
->orderByDesc('id')
->limit($count)
->get();
$this->info("Dispatching {$activities->count()} MatchActivityCrmData jobs (portal={$config->getId()})");
foreach ($activities as $activity) {
MatchActivityCrmData::dispatch($activity->getId(), $config, true);
}
$this->info('Done. Watch logs and run jiminny:debug observeRateLimit to inspect cache state.');
}
private function simulateVerifyTaskStorm(int $teamId = 2, int $count = 100): void
{
$activities = Activity::query()
->where('team_id', $teamId)
->whereNotNull('crm_provider_id')
->orderByDesc('id')
->limit($count)
->get();
$this->info("Dispatching {$activities->count()} VerifyActivityCrmTaskJob jobs");
foreach ($activities as $activity) {
VerifyActivityCrmTaskJob::dispatch($activity->getId());
}
$this->info('Done.');
}
private function observeRateLimitCache(int $teamId = 2): void
{
$team = Team::find($teamId);
$config = $team->getCrmConfiguration();
$key = sprintf('hubspot:ratelimit:portal:%d', $config->getId());
$value = Redis::get($key);
$ttl = Redis::ttl($key);
$this->info("Redis key: {$key}");
$this->info('Value: ' . ($value ?? '(empty)'));
$this->info("TTL: {$ttl}s");
}
}
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;
https://app.hubspot.com/contacts/4392066/deal/16964514951/?engagement=96069102624
https://app.staging.jiminny.com/playback/d5df34dc-bd66-4ff5-a7b3-8d3be30322a0
SELECT * FROM activities WHERE uuid_to_bin('04fdcd0d-818f-4c53-92dc-6f18bc753ffd') = uuid;
# 609126 softphone tr. 11241
SELECT * FROM activities WHERE uuid_to_bin('6521bfcd-5a30-46e5-9f74-5440fd48befd') = uuid;
# 608874 conference tr. 11226 crmId: 103422236596
select * from ai_prompts where transcription_id IN (11241, 11226);
select * from activity_summary_logs where activity_id = 608874;
select * from sidekick_settings;
select * from default_activity_types;
select * from crm_field_data where activity_id = 1223;
select * from crm_layouts where crm_configuration_id = 2;
SELECT * FROM crm_layout_entities WHERE crm_layout_id IN (554);
select * from crm_fields where crm_configuration_id = 11 and object_type = 'event';
SELECT * FROM crm_field_values WHERE crm_field_id IN (1455,1450);
SELECT * FROM crm_field_data WHERE crm_layout_entity_id = 971;
SELECT * FROM crm_field_data WHERE crm_layout_entity_id IN (6494,6495,6496,6497,6498,6499);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u
on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 2 and sa.provider = 'hubspot';
select * from social_accounts where id = 1499;
select * from opportunities where team_id = 2
and crm_provider_id IN ('51317301383');
select * from contacts where id = 85;
select * from opportunities where team_id = 2 order by id desc;
select * from opportunities where team_id = 2 and crm_provider_id = '51317301383'; # 5112
select * from opportunities where team_id = 2 and crm_provider_id = '55976759904'; # 5112
select * from opportunity_contacts where opportunity_id = 5117;
select * from crm_field_data where object_id = 1365;
SELECT * FROM crm_fields WHERE id IN (1405, 1407, 1972, 2128);
select * from features;
select * from team_features where team_id IN (1);
select * from team_features where feature_id IN (36);
SHOW CREATE TABLE opportunity_contacts;
SELECT * FROM opportunity_contacts WHERE crm_provider_id = '111751';
# $slug = 'HUBSPOT_WEBHOOK_SYNC';
# $team = Jiminny\Models\Team::find(2);
# $feature = Feature::query()->where('slug', $slug)->first();
# TeamFeature::query()->create(['feature_id' => $feature->getId(),'team_id' => $team->getId()]);
# hubspot_webhook_metrics
select * from opportunities where team_id = 2 and crm_provider_id IN ('374720564','14527423589','49908861993','50435771779'); # 1365
SELECT * FROM opportunity_contacts WHERE opportunity_id = '414';
SELECT * FROM opportunity_contacts WHERE crm_provider_id = '131501';
select * from contacts where id in (414, 464);
select * from activities where crm_configuration_id = 2;
select settings from crm_configurations where id = 11;
select * from teams; # 1, 2
select * from users;
select * from crm_configurations where id = 39;
select * from team_features where team_id = 2;
select * from features;
# SELECT * FROM opportunities WHERE crm_configuration_id = 2
# order by id desc;
# and crm_provider_id = '49908861993';
select * from activity_providers where id IN (443, 202, 203, 227);
select * from activity_imports where id = 795889;
select c.id, c.provider, c.settings, t.* from teams t join crm_configurations c on t.id = c.team_id
where c.provider = 'hubspot';
select * from crm_configurations crm JOIN teams t on crm.team_id = t.id
where provider = 'hubspot';
SELECT * FROM teams WHERE id = 31;
SELECT * FROM users WHERE id = 257;
SELECT * FROM opportunities WHERE team_id = 2;
select * from opportunity_contacts where opportunity_id = 5124;
select * from contacts where id IN (3850,3853,3851,4073,4140,4155,4480,4530,4623,5986,513,687,1806,1523,3613)
select * from activities where crm_configuration_id = 13;
SELECT * FROM activities WHERE uuid_to_bin('826619ce-ec8e-4e59-8467-a01f5f6ad71e') = uuid; # 418141
select id, team_id, crm_provider_id from crm_configurations where provider = 'hubspot' and crm_provider_id IS NOT NULL;
SELECT * FROM accounts WHERE team_id = 2 and crm_provider_id = '1212213464' order by id desc;
SELECT * FROM contacts WHERE team_id = 2 and account_id = 5189 order by id desc;
SELECT * FROM contacts WHERE team_id = 2 order by id desc;
select * from opportunity_contacts where contact_id = 6223;
SELECT * FROM opportunities WHERE team_id = 2 and account_id = 5189 order by id desc;
select * from crm_profiles where crm_configuration_id = 2;
select * from activities where account_id = 46;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20725-handle-HS-search-rate-limit, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09541223,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20725-handle-HS-search-rate-limit","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.82413566,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"HandleHubspotRateLimitTest","depth":6,"bounds":{"left":0.8394282,"top":0.019952115,"width":0.076130316,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'HandleHubspotRateLimitTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'HandleHubspotRateLimitTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"5","depth":4,"bounds":{"left":0.5043218,"top":0.17478053,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"133","depth":4,"bounds":{"left":0.5142952,"top":0.17478053,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"11","depth":4,"bounds":{"left":0.52825797,"top":0.17478053,"width":0.008976064,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.53889626,"top":0.17318435,"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.5462101,"top":0.17318435,"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\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\Facades\\Redis;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\Crm\\Delete\\VerifyActivityCrmTaskJob;\nuse Jiminny\\Jobs\\Crm\\MatchActivityCrmData;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n // Choose ONE of the following to run, then comment out the others.\n // 1) Dispatch a storm of MatchActivityCrmData jobs against team 2\n $this->simulateMatchActivityStorm(teamId: 2, count: 100);\n\n // 2) Dispatch a storm of VerifyActivityCrmTaskJob jobs (simulates DeleteCrmEntityTrait fan-out)\n // $this->simulateVerifyTaskStorm(teamId: 2, count: 100);\n\n // 3) Inspect Redis circuit-breaker state for the team's HubSpot portal\n // $this->observeRateLimitCache(teamId: 2);\n\n // 4) Make 3 synchronous matchByName calls (foreground, hits API directly)\n // $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 3; $i++) {\n// if ($i % 25 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n// }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchByName('Robot');\n }\n }\n\n private function simulateMatchActivityStorm(int $teamId = 2, int $count = 100): void\n {\n $team = Team::find($teamId);\n $config = $team->getCrmConfiguration();\n\n $activities = Activity::query()\n ->where('crm_configuration_id', $config->getId())\n ->orderByDesc('id')\n ->limit($count)\n ->get();\n\n $this->info(\"Dispatching {$activities->count()} MatchActivityCrmData jobs (portal={$config->getId()})\");\n\n foreach ($activities as $activity) {\n MatchActivityCrmData::dispatch($activity->getId(), $config, true);\n }\n\n $this->info('Done. Watch logs and run jiminny:debug observeRateLimit to inspect cache state.');\n }\n\n private function simulateVerifyTaskStorm(int $teamId = 2, int $count = 100): void\n {\n $activities = Activity::query()\n ->where('team_id', $teamId)\n ->whereNotNull('crm_provider_id')\n ->orderByDesc('id')\n ->limit($count)\n ->get();\n\n $this->info(\"Dispatching {$activities->count()} VerifyActivityCrmTaskJob jobs\");\n\n foreach ($activities as $activity) {\n VerifyActivityCrmTaskJob::dispatch($activity->getId());\n }\n\n $this->info('Done.');\n }\n\n private function observeRateLimitCache(int $teamId = 2): void\n {\n $team = Team::find($teamId);\n $config = $team->getCrmConfiguration();\n $key = sprintf('hubspot:ratelimit:portal:%d', $config->getId());\n\n $value = Redis::get($key);\n $ttl = Redis::ttl($key);\n\n $this->info(\"Redis key: {$key}\");\n $this->info('Value: ' . ($value ?? '(empty)'));\n $this->info(\"TTL: {$ttl}s\");\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\Facades\\Redis;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\Crm\\Delete\\VerifyActivityCrmTaskJob;\nuse Jiminny\\Jobs\\Crm\\MatchActivityCrmData;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n // Choose ONE of the following to run, then comment out the others.\n // 1) Dispatch a storm of MatchActivityCrmData jobs against team 2\n $this->simulateMatchActivityStorm(teamId: 2, count: 100);\n\n // 2) Dispatch a storm of VerifyActivityCrmTaskJob jobs (simulates DeleteCrmEntityTrait fan-out)\n // $this->simulateVerifyTaskStorm(teamId: 2, count: 100);\n\n // 3) Inspect Redis circuit-breaker state for the team's HubSpot portal\n // $this->observeRateLimitCache(teamId: 2);\n\n // 4) Make 3 synchronous matchByName calls (foreground, hits API directly)\n // $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 3; $i++) {\n// if ($i % 25 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n// }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchByName('Robot');\n }\n }\n\n private function simulateMatchActivityStorm(int $teamId = 2, int $count = 100): void\n {\n $team = Team::find($teamId);\n $config = $team->getCrmConfiguration();\n\n $activities = Activity::query()\n ->where('crm_configuration_id', $config->getId())\n ->orderByDesc('id')\n ->limit($count)\n ->get();\n\n $this->info(\"Dispatching {$activities->count()} MatchActivityCrmData jobs (portal={$config->getId()})\");\n\n foreach ($activities as $activity) {\n MatchActivityCrmData::dispatch($activity->getId(), $config, true);\n }\n\n $this->info('Done. Watch logs and run jiminny:debug observeRateLimit to inspect cache state.');\n }\n\n private function simulateVerifyTaskStorm(int $teamId = 2, int $count = 100): void\n {\n $activities = Activity::query()\n ->where('team_id', $teamId)\n ->whereNotNull('crm_provider_id')\n ->orderByDesc('id')\n ->limit($count)\n ->get();\n\n $this->info(\"Dispatching {$activities->count()} VerifyActivityCrmTaskJob jobs\");\n\n foreach ($activities as $activity) {\n VerifyActivityCrmTaskJob::dispatch($activity->getId());\n }\n\n $this->info('Done.');\n }\n\n private function observeRateLimitCache(int $teamId = 2): void\n {\n $team = Team::find($teamId);\n $config = $team->getCrmConfiguration();\n $key = sprintf('hubspot:ratelimit:portal:%d', $config->getId());\n\n $value = Redis::get($key);\n $ttl = Redis::ttl($key);\n\n $this->info(\"Redis key: {$key}\");\n $this->info('Value: ' . ($value ?? '(empty)'));\n $this->info(\"TTL: {$ttl}s\");\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.55485374,"top":0.074221864,"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.56349736,"top":0.074221864,"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.5744681,"top":0.074221864,"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.5831117,"top":0.074221864,"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.59175533,"top":0.074221864,"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.60272604,"top":0.074221864,"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.6136968,"top":0.074221864,"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.6402925,"top":0.074221864,"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.6512633,"top":0.074221864,"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.9587766,"top":0.074221864,"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.94514626,"top":0.09896249,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.95511967,"top":0.09896249,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"6","depth":4,"bounds":{"left":0.9644282,"top":0.09896249,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.9740692,"top":0.09736632,"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.98138297,"top":0.09736632,"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":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}]...
|
3747474787770407699
|
1784479456135954157
|
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
5
133
11
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\Crm\Delete\VerifyActivityCrmTaskJob;
use Jiminny\Jobs\Crm\MatchActivityCrmData;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
// Choose ONE of the following to run, then comment out the others.
// 1) Dispatch a storm of MatchActivityCrmData jobs against team 2
$this->simulateMatchActivityStorm(teamId: 2, count: 100);
// 2) Dispatch a storm of VerifyActivityCrmTaskJob jobs (simulates DeleteCrmEntityTrait fan-out)
// $this->simulateVerifyTaskStorm(teamId: 2, count: 100);
// 3) Inspect Redis circuit-breaker state for the team's HubSpot portal
// $this->observeRateLimitCache(teamId: 2);
// 4) Make 3 synchronous matchByName calls (foreground, hits API directly)
// $this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 3; $i++) {
// if ($i % 25 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
// }
// $crmService->syncOpportunity('374720564');
$crmService->matchByName('Robot');
}
}
private function simulateMatchActivityStorm(int $teamId = 2, int $count = 100): void
{
$team = Team::find($teamId);
$config = $team->getCrmConfiguration();
$activities = Activity::query()
->where('crm_configuration_id', $config->getId())
->orderByDesc('id')
->limit($count)
->get();
$this->info("Dispatching {$activities->count()} MatchActivityCrmData jobs (portal={$config->getId()})");
foreach ($activities as $activity) {
MatchActivityCrmData::dispatch($activity->getId(), $config, true);
}
$this->info('Done. Watch logs and run jiminny:debug observeRateLimit to inspect cache state.');
}
private function simulateVerifyTaskStorm(int $teamId = 2, int $count = 100): void
{
$activities = Activity::query()
->where('team_id', $teamId)
->whereNotNull('crm_provider_id')
->orderByDesc('id')
->limit($count)
->get();
$this->info("Dispatching {$activities->count()} VerifyActivityCrmTaskJob jobs");
foreach ($activities as $activity) {
VerifyActivityCrmTaskJob::dispatch($activity->getId());
}
$this->info('Done.');
}
private function observeRateLimitCache(int $teamId = 2): void
{
$team = Team::find($teamId);
$config = $team->getCrmConfiguration();
$key = sprintf('hubspot:ratelimit:portal:%d', $config->getId());
$value = Redis::get($key);
$ttl = Redis::ttl($key);
$this->info("Redis key: {$key}");
$this->info('Value: ' . ($value ?? '(empty)'));
$this->info("TTL: {$ttl}s");
}
}
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;
https://app.hubspot.com/contacts/4392066/deal/16964514951/?engagement=96069102624
https://app.staging.jiminny.com/playback/d5df34dc-bd66-4ff5-a7b3-8d3be30322a0
SELECT * FROM activities WHERE uuid_to_bin('04fdcd0d-818f-4c53-92dc-6f18bc753ffd') = uuid;
# 609126 softphone tr. 11241
SELECT * FROM activities WHERE uuid_to_bin('6521bfcd-5a30-46e5-9f74-5440fd48befd') = uuid;
# 608874 conference tr. 11226 crmId: 103422236596
select * from ai_prompts where transcription_id IN (11241, 11226);
select * from activity_summary_logs where activity_id = 608874;
select * from sidekick_settings;
select * from default_activity_types;
select * from crm_field_data where activity_id = 1223;
select * from crm_layouts where crm_configuration_id = 2;
SELECT * FROM crm_layout_entities WHERE crm_layout_id IN (554);
select * from crm_fields where crm_configuration_id = 11 and object_type = 'event';
SELECT * FROM crm_field_values WHERE crm_field_id IN (1455,1450);
SELECT * FROM crm_field_data WHERE crm_layout_entity_id = 971;
SELECT * FROM crm_field_data WHERE crm_layout_entity_id IN (6494,6495,6496,6497,6498,6499);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u
on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 2 and sa.provider = 'hubspot';
select * from social_accounts where id = 1499;
select * from opportunities where team_id = 2
and crm_provider_id IN ('51317301383');
select * from contacts where id = 85;
select * from opportunities where team_id = 2 order by id desc;
select * from opportunities where team_id = 2 and crm_provider_id = '51317301383'; # 5112
select * from opportunities where team_id = 2 and crm_provider_id = '55976759904'; # 5112
select * from opportunity_contacts where opportunity_id = 5117;
select * from crm_field_data where object_id = 1365;
SELECT * FROM crm_fields WHERE id IN (1405, 1407, 1972, 2128);
select * from features;
select * from team_features where team_id IN (1);
select * from team_features where feature_id IN (36);
SHOW CREATE TABLE opportunity_contacts;
SELECT * FROM opportunity_contacts WHERE crm_provider_id = '111751';
# $slug = 'HUBSPOT_WEBHOOK_SYNC';
# $team = Jiminny\Models\Team::find(2);
# $feature = Feature::query()->where('slug', $slug)->first();
# TeamFeature::query()->create(['feature_id' => $feature->getId(),'team_id' => $team->getId()]);
# hubspot_webhook_metrics
select * from opportunities where team_id = 2 and crm_provider_id IN ('374720564','14527423589','49908861993','50435771779'); # 1365
SELECT * FROM opportunity_contacts WHERE opportunity_id = '414';
SELECT * FROM opportunity_contacts WHERE crm_provider_id = '131501';
select * from contacts where id in (414, 464);
select * from activities where crm_configuration_id = 2;
select settings from crm_configurations where id = 11;
select * from teams; # 1, 2
select * from users;
select * from crm_configurations where id = 39;
select * from team_features where team_id = 2;
select * from features;
# SELECT * FROM opportunities WHERE crm_configuration_id = 2
# order by id desc;
# and crm_provider_id = '49908861993';
select * from activity_providers where id IN (443, 202, 203, 227);
select * from activity_imports where id = 795889;
select c.id, c.provider, c.settings, t.* from teams t join crm_configurations c on t.id = c.team_id
where c.provider = 'hubspot';
select * from crm_configurations crm JOIN teams t on crm.team_id = t.id
where provider = 'hubspot';
SELECT * FROM teams WHERE id = 31;
SELECT * FROM users WHERE id = 257;
SELECT * FROM opportunities WHERE team_id = 2;
select * from opportunity_contacts where opportunity_id = 5124;
select * from contacts where id IN (3850,3853,3851,4073,4140,4155,4480,4530,4623,5986,513,687,1806,1523,3613)
select * from activities where crm_configuration_id = 13;
SELECT * FROM activities WHERE uuid_to_bin('826619ce-ec8e-4e59-8467-a01f5f6ad71e') = uuid; # 418141
select id, team_id, crm_provider_id from crm_configurations where provider = 'hubspot' and crm_provider_id IS NOT NULL;
SELECT * FROM accounts WHERE team_id = 2 and crm_provider_id = '1212213464' order by id desc;
SELECT * FROM contacts WHERE team_id = 2 and account_id = 5189 order by id desc;
SELECT * FROM contacts WHERE team_id = 2 order by id desc;
select * from opportunity_contacts where contact_id = 6223;
SELECT * FROM opportunities WHERE team_id = 2 and account_id = 5189 order by id desc;
select * from crm_profiles where crm_configuration_id = 2;
select * from activities where account_id = 46;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
18265
|
NULL
|
NULL
|
NULL
|
|
18270
|
790
|
40
|
2026-05-11T11:07:34.860056+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778497654860_m1.jpg...
|
Notion Calendar
|
NULL
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ab)Preparation for Refi... in 53 mDEV (docker)-zshDOCKER- ₴81DEV (docker)₴2APP (-zsh)H3worker-crm-update:worker-crm-update_00: stoppedworker-download:worker-download_00:stoppedworker-nudges:worker-nudges_00:stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedworker:worker_00: stoppedworker-calendar:worker-calendar_00:stoppedworker-conferences:worker-conferences_00:stoppedworker-crm-sync:worker-crm-sync_00:stoppedworker-es-update:worker-es-update_00: stoppedworker-emails:worker-emails_00: stoppedworker-audio:worker-audio_00: stoppedartisan-schedule:artisan-schedule_00:stoppedartisan-schedule:artisan-schedule_00:startedjiminny-worker-processing-1:jiminny-worker-processing-1_00: startedjiminny-worker-processing-2:jiminny-worker-processing-2_00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00: startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00: startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00: startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny# php artisan jiminny:debugDispatching 100 MatchActivityCrmDatajobs (portal=2)Done.Watch logs and run jiminny:debug observeRateLimit to inspect cachestate.root@docker_lamp_1:/home/jiminny# php artisan optimize:clear && supervisorctl restart allINFOClearing cached bootstrap files.configcachecompiledeventsroutesviews84-zshX5screenpipe"100% <8• Mon 11 May 14:07:34181O ₴6-zsh87+DEV59.22ms DONE97.76ms DONE2.63ms DONE4.67ms DONE11.57ms DONE18.54ms DONE...
|
NULL
|
-7225465322759668190
|
NULL
|
click
|
ocr
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ab)Preparation for Refi... in 53 mDEV (docker)-zshDOCKER- ₴81DEV (docker)₴2APP (-zsh)H3worker-crm-update:worker-crm-update_00: stoppedworker-download:worker-download_00:stoppedworker-nudges:worker-nudges_00:stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedworker:worker_00: stoppedworker-calendar:worker-calendar_00:stoppedworker-conferences:worker-conferences_00:stoppedworker-crm-sync:worker-crm-sync_00:stoppedworker-es-update:worker-es-update_00: stoppedworker-emails:worker-emails_00: stoppedworker-audio:worker-audio_00: stoppedartisan-schedule:artisan-schedule_00:stoppedartisan-schedule:artisan-schedule_00:startedjiminny-worker-processing-1:jiminny-worker-processing-1_00: startedjiminny-worker-processing-2:jiminny-worker-processing-2_00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00: startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00: startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00: startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny# php artisan jiminny:debugDispatching 100 MatchActivityCrmDatajobs (portal=2)Done.Watch logs and run jiminny:debug observeRateLimit to inspect cachestate.root@docker_lamp_1:/home/jiminny# php artisan optimize:clear && supervisorctl restart allINFOClearing cached bootstrap files.configcachecompiledeventsroutesviews84-zshX5screenpipe"100% <8• Mon 11 May 14:07:34181O ₴6-zsh87+DEV59.22ms DONE97.76ms DONE2.63ms DONE4.67ms DONE11.57ms DONE18.54ms DONE...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
18367
|
792
|
40
|
2026-05-11T11:13:27.452407+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778498007452_m1.jpg...
|
PhpStorm
|
faVsco.js – laravel.log
|
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...
|
[{"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}]...
|
1684527879063584500
|
-8348266015821985344
|
click
|
hybrid
|
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
iTerm2ShellEditViewSessionScriptsProfilesWindowHelpDEV (docker)-zsh$084(ab)§ Preparation for Refi... in 47 mDOCKER- ₴81DEV (docker)₴2APP (-zsh)H3worker-crm-update:worker-crm-update_00: stoppedworker-download:worker-download_00:stoppedworker-nudges:worker-nudges_00: stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedworker-emails:worker-emails_00: stoppedworker:worker_00: stoppedworker-audio:worker-audio_00: stoppedworker-calendar:worker-calendar_00:stoppedworker-conferences:worker-conferences_00: stoppedworker-crm-sync:worker-crm-sync_00:stoppedworker-es-update:worker-es-update_00: stoppedartisan-schedule:artisan-schedule_00: stoppedartisan-schedule:artisan-schedule_00: startedjiminny-worker-processing-1:jiminny-worker-processing-1_00: startedjiminny-worker-processing-2:jiminny-worker-processing-2_00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00: startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00: startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00: startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny# php artisan jiminny: debugDispatching 100 MatchActivityCrmDatajobs (portal=2)Done.Watch logs and run jiminny:debug observeRateLimit to inspect cachestate.root@docker_lamp_1:/home/jiminny# php artisan optimize:clear && supervisorctl restart allINFOClearing cached bootstrap files.configcachecompiledeventsroutesviews-zshX5screenpipe"100% <8• Mon 11 May 14:13:27181O ₴6-zsh+DEV4.18ms DONE11.06ms DONE1.84ms DONE1.32ms DONE1.43ms DONE21.19ms DONE...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
18450
|
794
|
40
|
2026-05-11T11:18:17.364466+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778498297364_m1.jpg...
|
PhpStorm
|
faVsco.js – laravel.log
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelpPreparation for Refi... in 42 mDEV (docker)-zshDOCKER- ₴81DEV (docker)$2APP (-zsh)*3compiledeventsroutesviewsJiminny-worker-processing-2:j1minny-worker-processing-2_00: stoppedjiminny-worker-processing-3:jiminny-worker-processing-3_00: stoppedjiminny-worker-processing-4:jiminny-worker-processing-4_00: stoppedjiminny-worker-processing-5:jiminny-worker-processing-5_00: stoppedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00:stoppedworker-analytics:worker-analytics_00: stoppedworker-audio:worker-audio_00:stoppedworker-crm-update:worker-crm-update_00:stoppedworker-download:worker-download_00:stoppedworker-nudges:worker-nudges_00:stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedworker:worker_00: stoppedworker-calendar:worker-calendar_00:stoppedworker-conferences:worker-conferences_00: stoppedworker-crm-sync:worker-crm-sync_00:stoppedworker-emails:worker-emails_00: stoppedworker-es-update:worker-es-update_00: stoppedartisan-schedule:artisan-schedule_00: stoppedartisan-schedule:artisan-schedule_00: startedjiminny-worker-processing-1:jiminny-worker-processing-1_00: startedjiminny-worker-processing-2:jiminny-worker-processing-2_00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00:startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00: startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00:startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny#php artisan jiminny:debugDispatching 100 MatchActivityCrmDatajobs (portal=2)Done.Watch logs and runjiminny:debug observeRateLimit to inspect cachestate.root@docker_lamp_1:/home/jiminny# ]84-zshX5100% <78• Mon 11 May 14:18:16T81-zsh+screenpipe"O 8861.79ms DONE2.06ms DONE0.85ms DONE4.12ms DONEDEV...
|
NULL
|
3710687757202135288
|
NULL
|
click
|
ocr
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelpPreparation for Refi... in 42 mDEV (docker)-zshDOCKER- ₴81DEV (docker)$2APP (-zsh)*3compiledeventsroutesviewsJiminny-worker-processing-2:j1minny-worker-processing-2_00: stoppedjiminny-worker-processing-3:jiminny-worker-processing-3_00: stoppedjiminny-worker-processing-4:jiminny-worker-processing-4_00: stoppedjiminny-worker-processing-5:jiminny-worker-processing-5_00: stoppedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00:stoppedworker-analytics:worker-analytics_00: stoppedworker-audio:worker-audio_00:stoppedworker-crm-update:worker-crm-update_00:stoppedworker-download:worker-download_00:stoppedworker-nudges:worker-nudges_00:stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedworker:worker_00: stoppedworker-calendar:worker-calendar_00:stoppedworker-conferences:worker-conferences_00: stoppedworker-crm-sync:worker-crm-sync_00:stoppedworker-emails:worker-emails_00: stoppedworker-es-update:worker-es-update_00: stoppedartisan-schedule:artisan-schedule_00: stoppedartisan-schedule:artisan-schedule_00: startedjiminny-worker-processing-1:jiminny-worker-processing-1_00: startedjiminny-worker-processing-2:jiminny-worker-processing-2_00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00:startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00: startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00:startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny#php artisan jiminny:debugDispatching 100 MatchActivityCrmDatajobs (portal=2)Done.Watch logs and runjiminny:debug observeRateLimit to inspect cachestate.root@docker_lamp_1:/home/jiminny# ]84-zshX5100% <78• Mon 11 May 14:18:16T81-zsh+screenpipe"O 8861.79ms DONE2.06ms DONE0.85ms DONE4.12ms DONEDEV...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
18644
|
803
|
40
|
2026-05-11T11:37:49.199419+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778499469199_m2.jpg...
|
PhpStorm
|
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Undo
Redo
Cut
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Undo","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Redo","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cut","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"}]...
|
-4359152175493110010
|
4017696282325708110
|
click
|
hybrid
|
NULL
|
Undo
Redo
Cut
PhpStormEV favsco.jsProjectViewINavi Undo
Redo
Cut
PhpStormEV favsco.jsProjectViewINavicareCodeLaravelg9 JY-20725-handle-HS-search-rate-limit ~KeractorTOOISWindow© OutOfBoundsException.pl•Hudspot/serwice.onp© HubSpot/Service.php$ SyncCrmEntitiesTrait.php© CachedCrmServiceDecorator.php© QuotaExceededException-kateLimitexception.ong© RegistrationInvitationMisnС CheскAnaкetrykemotematch.pnp© RequestQueuedForDeferrResponseException.phpc Job.pho© RingCentralException.php©PaginationState.phpC) MatchCrmData.phpC) CrmObiectsResolver.pho© ProviderRateLimiter.php© PaginationConfig.phpRingCentralExtensionNotl© RuntimeException.php<?php) SequenceNumberExceptideclare(strict_types=1);© ServicelntegrationExcepti() ServiceUnavailableExcepnamespace Jiminny\Exceptions;® SidekickSettingsExceptior() Socia Account NotFound:use Throwable;© SocialAccountTokeninvaliSvncActivitvExcention.ohclass RateLimitException extends RuntimeException© TenantisolationException. 10© TextRelayException.php11 đ© TooManyFailedActivities.i 124 TranscrintionNotindeyedi 12© UnexpectedCallException 14public function __construct(string smessage ="private readonly int $retryAfter = 1,cInrowable sprevious = nuut.® UnexpectedEloquentMod 15© UnexpectedValueExceptis 16parent:: constructsmessage.code: 0, Sprevious© ZipAttackException.php> DFFMpeg> D Formats> D Guardspublic tunction qetretryAttero: 1ntConsole xLogxChanges 12 filesE.env.local app© Client.php app/Services/Crm/Hubspot© HandleHubspotRateLimit.php app/Jobs/MiddlewareC HandleHubspotRateLimitTest.php tests/Unit/Jobs/Middleware© HubspotClientinterface.php app/Services/Crm/Hubspot© 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/Pagination© RateLimitException.pho app/Exceptions© RateLimitExceptionTest.php tests/Unit/ExceptionsUnversioned Files 9 files=env.nikilocal appenv.other aoo© CanAccessAiReportsTest.php tests/Unit/Policies(C) CreateMockAsk.liminnvReoortResultCommand.ohn aoo/Console/Commands/Rre tavicon ico nublic= ids tyt annTaraw_sqLquery.sgl appC)SimulateWehhookcCommand nhn ann/Console/Commands/Crm/HubsnotML WERHOOK FII TERING IMPI EMENTATION md annTacts naccod. 12 (todav 12:02T + 0+ → E Side-by-side viewer -Do not ignore© 35f036ac app/Exceptions/RateLimitException.phpHighight words -X 1 ?declare strict types=1)*namespace Jiminny Exceptions_class RateLimitException extends LogicExceptionA SF (jiminny@localhost]A HS_local (jiminny@localhost]# console [PRol)# console [eu)A console [STAGING)17131/141715171617171/18171917281727172817291730[2026-05-11 11:20:43] Local.ERROR: Failed to refresh HubSpot token {"account_id":1372, "updated_ vY454AV[2026-05-11 11:20:43] Local.NOTICE: Repairing HubSpot tokens end f"total":3, "fixed":0, "failed":3} f"correlation[2026-05-11 11:20:48] Local. INFO: Jiminny|Console\Commands\Command::run Memory usage before starting command {[2026-05-11 11:20:48] Local. INFO: Jiminny|Console\Commands\Command: :run Memory usage before starting command f"12020-05-11 11.20.48 LocaL.LNFU. LHUDspot Journal commandl scarting polling service1"correlac1on10: 754015[2026-05-11 11:20:48] Local. INFO:[HubSpot Journal Pollingl Service starting f"memory_Limit": "256M", "max_execut2020-05-11 11:20:48 Local. LNFU:Hubspor Journal Polling Acqulred polling lock ""expires ac: 2020-05-111159[2026-05-11 11:20:48] Local. INF0:2026-05-11 11.20.48 LocaL.LNFU:Jaminnyconsole commanos.comremory usage tor commano "commano"."7[2026-05-11 11:20:49] Local. INFO: Jiminny|Console\Commands\Command: :run Memory usage for command €"co2826-05-11 11:20:49 Local.INF0:HubSoot Journal Auth Successfully obtained new access token «"expires_1n":[2026-05-11 11:20:49] Local. INFO: [HubSpot Journal Polling] No data2826-05-11 11:20:53 Local.INF0:Jaminny Console Commands Command:: runMemory usage before starting command[2026-05-11 11:20:53] Local. INFO: Jiminny\Console\Commands\Command: :run Memory usage for command ("command" :"crLocaL.INFo: HuoSoot Journal Pollinal No datal[2026-05-11 11:20:56]local. INFO: Jiminny\Console\Commands\Command: :run Memory usage before starting command {"[2026-05-11 11:20:57] local.INF0: Jiminny \Console \Commands \Command::run Memory usage for command t"command":"cr2026-05-11 11:20:591 Loc0lINF0: HubSoot Journal Pollinal No data"correlation 1d"."954d156d-8a4f-4592-a046$0• Preparation Tor Kerl.. In 23 mU HandleHubspotRateLimitTest~100% 28• Mon 11 May 14:37:48Hubspot Rate Limit Re+0 ...Tests: RateLimitExcentionTest doesn't assert the parent class, so all 6 tests stilli pass after the revertMiddleware: catches RateLimitException directly (by class, not parent), unaffected.• MatchActivitvermbata: Se instanceot RatelimitExceotion check. unattected.• Cache circuit-breaker: throw new RateLimitException(...) in Client: : executeRequest, unaffected.One semanuc note (ryl, поr ооckine)PHP/SPL convention treats LogicException as "bug in program logic" (something a code change should fix) and RuntimeException as "condition only detectable at runtime" (network failures, rate limits, missing files). A 429 from an externalAPl is squarely runtimeThat said - if existing callers in the codebase catch it as LogicException and you'd break them by changing it, backwardcompat wins. The catch sites likely look something like:O bashgrep -rn "catch.*LogicException" app/ | grep -i rateIf those are intentional, sticking with LogicException is the pragmatic call. If any of them were just imitating an outdatedconvention, this would be the moment to fix them — but that's a separate cleanup, not blockingEither way, no further changes needed from me. The revert is safe.toal "ou've used 95% of your quota. Quota resets May 12, 11:00 AM GMT+3Ok Where is it used, will I break something it is replace LogicException with|Undo<> CodeClaude Opus 4.7 MediumPastePaste and Match StyleSelect AllOpen DevToolsdifferencescurrent versiondeclare(strict_ types=1)*namespace Jiminny Exceptions:use Throwable;class RateLimitExcention extends RuntimeExcentionpublic function __construct(Strina Smessage =private readonly int SretryAfter = 1,Throwahil e Sarevious = nuinarent.• construct(Smecsade. A Snrevious)•public function getRetryAfter(): intreturn max($this->retryAfter, 1);W Windsurf Toams 0.25(18 charc) UTF.8f 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
18651
|
802
|
40
|
2026-05-11T11:38:27.112642+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778499507112_m1.jpg...
|
PhpStorm
|
faVsco.js – RateLimitException.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 Jiminny\Exceptions;
use Throwable;
class RateLimitException extends RuntimeException
{
public function __construct(
string $message = '',
private readonly int $retryAfter = 1,
?Throwable $previous = null,
) {
parent::__construct($message, 0, $previous);
}
public function getRetryAfter(): int
{
return max($this->retryAfter, 1);
}
}
Show Replace Field
Search History
429
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
23/38
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
454
Previous Highlighted Error
Next Highlighted Error
[2026-05-11 11:17:21] local.NOTICE: Monitoring start {"correlation_id":"885fde59-3852-4120-a620-af3da7ecce17","trace_id":"4cc10f53-5d39-418d-8e98-fe53d9bbff5f"}
[2026-05-11 11:17:21] local.NOTICE: Monitoring end {"correlation_id":"885fde59-3852-4120-a620-af3da7ecce17","trace_id":"4cc10f53-5d39-418d-8e98-fe53d9bbff5f"}
[2026-05-11 11:17:34] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":60.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a773fb28-5a0c-4b8f-a1b5-d57e6b81db90","trace_id":"fb6d8028-db7d-4ef2-b175-740f0a7b8b39"}
[2026-05-11 11:17:35] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":60.0,"memoryAfterCommandInMB":60.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"a773fb28-5a0c-4b8f-a1b5-d57e6b81db90","trace_id":"fb6d8028-db7d-4ef2-b175-740f0a7b8b39"}
[2026-05-11 11:17:37] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":615092,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":null,"account_id":26,"opportunity_id":22,"stage_id":89}} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:37] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":615092} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:37] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":615092,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:37] local.INFO: [MatchActivityCrmData] Participants old state {"activity":615092,"participants":[{"id":1004102,"user_id":null,"contact_id":null,"lead_id":null},{"id":1004103,"user_id":89,"contact_id":null,"lead_id":null}]} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:37] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:37] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:37] local.INFO: [Prospect match] Cache miss, calling the API {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [Hubspot] Failed to fetch contact {"email":"[EMAIL]","reason":"[404] Client error: `GET https://api.hubapi.com/crm/v3/objects/contacts/nikolay.nikolov%40jiminny.com?properties=email%2Cfirstname%2Clastname%2Ccountry%2Cphone%2Cmobilephone%2Cjobtitle%2Chubspot_owner_id%2Cassociatedcompanyid%2Cphoto&archived=0&idProperty=email` resulted in a `404 Not Found` response"} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [Prospect match] API returned empty result, caching the miss with empty prospect data {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.WARNING: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":1,"reason":"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\":\"019e16c1-c (truncated...)
"} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {"job_class":"Jiminny\\Jobs\\Crm\\MatchActivityCrmData","attempts":1,"retry_after":1,"delay":4} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":614436,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":null,"account_id":26,"opportunity_id":22,"stage_id":89}} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":614436} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":614436,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [MatchActivityCrmData] Participants old state {"activity":614436,"participants":[{"id":1002751,"user_id":null,"contact_id":null,"lead_id":null},{"id":1002752,"user_id":89,"contact_id":null,"lead_id":null}]} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {"job_class":"Jiminny\\Jobs\\Crm\\MatchActivityCrmData","attempts":1,"retry_after":1,"delay":3} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":614382,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":null,"account_id":26,"opportunity_id":22,"stage_id":89}} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":614382} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":614382,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Participants old state {"activity":614382,"participants":[{"id":1002632,"user_id":null,"contact_id":null,"lead_id":null},{"id":1002633,"user_id":89,"contact_id":null,"lead_id":null}]} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {"job_class":"Jiminny\\Jobs\\Crm\\MatchActivityCrmData","attempts":1,"retry_after":1,"delay":1} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":614381,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":null,"account_id":26,"opportunity_id":22,"stage_id":89}} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":614381} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":614381,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Participants old state {"activity":614381,"participants":[{"id":1002630,"user_id":null,"contact_id":null,"lead_id":null},{"id":1002631,"user_id":89,"contact_id":null,"lead_id":null}]} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.WARNING: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":1,"reason":"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\":\"019e16c1-c (truncated...)
"} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {"job_class":"Jiminny\\Jobs\\Crm\\MatchActivityCrmData","attempts":1,"retry_after":1,"delay":2} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":614378,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":6167,"account_id":null,"opportunity_id":null,"stage_id":null}} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":614378} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":614378,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Participants old state {"activity":614378,"participants":[{"id":1002623,"user_id":null,"contact_id":null,"lead_id":null},{"id":1002624,"user_id":null,"contact_id":6167,"lead_id":null},{"id":1002625,"user_id":89,"contact_id":null,"lead_id":null}]} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {"job_class":"Jiminny\\Jobs\\Crm\\MatchActivityCrmData","attempts":1,"retry_after":1,"delay":3} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":613840,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36}} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613840} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613840,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {"activity":613840,"participants":[{"id":1001764,"user_id":null,"contact_id":4487,"lead_id":null},{"id":1001765,"user_id":261,"contact_id":null,"lead_id":null}]} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: ProspectCache - Searching DB for opportunity by owner {"account_id":244,"contact_id":4487,"owner_id":261} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: ProspectCache - Opportunity DB search results {"account_id":244,"contact_id":4487,"opportunity_id":299} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":613840,"team_id":2,"email":"[EMAIL]"} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {"activity_id":613840,"participants_processed":2,"exact_matches":1,"domain_matches":0,"best_match_found":true} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613840} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613840,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {"activity":613840,"remote_search":true,"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":613833,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36}} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613833} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613833,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {"activity":613833,"participants":[{"id":1001750,"user_id":null,"contact_id":4487,"lead_id":null},{"id":1001751,"user_id":261,"contact_id":null,"lead_id":null}]} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {"worker":"","peak_memory":"99.73 MB","elapsed_seconds":1.0,"update_target":"activities","should_iterate_again":false} {"correlation_id":"8c24420c-db53-4450-9cd8-db5d2426bd57","trace_id":"5406d133-f6cd-4f5a-b463-9146e1dfb021"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":613833,"team_id":2,"email":"[EMAIL]"} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {"activity_id":613833,"participants_processed":2,"exact_matches":1,"domain_matches":0,"best_match_found":true} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613833} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613833,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {"activity":613833,"remote_search":true,"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":613827,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36}} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613827} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613827,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {"activity":613827,"participants":[{"id":1001734,"user_id":null,"contact_id":4487,"lead_id":null},{"id":1001735,"user_id":261,"contact_id":null,"lead_id":null}]} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":613827,"team_id":2,"email":"[EMAIL]"} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {"activity_id":613827,"participants_processed":2,"exact_matches":1,"domain_matches":0,"best_match_found":true} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613827} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613827,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {"activity":613827,"remote_search":true,"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":613826,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36}} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613826} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613826,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {"activity":613826,"participants":[{"id":1001732,"user_id":null,"contact_id":4487,"lead_id":null},{"id":1001733,"user_id":261,"contact_id":null,"lead_id":null}]} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":613826,"team_id":2,"email":"[EMAIL]"} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {"activity_id":613826,"participants_processed":2,"exact_matches":1,"domain_matches":0,"best_match_found":true} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613826} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613826,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {"activity":613826,"remote_search":true,"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":613820,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36}} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613820} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613820,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {"activity":613820,"participants":[{"id":1001721,"user_id":null,"contact_id":4487,"lead_id":null},{"id":1001722,"user_id":261,"contact_id":null,"lead_id":null}]} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":613820,"team_id":2,"email":"[EMAIL]"} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {"activity_id":613820,"participants_processed":2,"exact_matches":1,"domain_matches":0,"best_match_found":true} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613820} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613820,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {"activity":613820,"remote_search":true,"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":613818,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36}} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613818} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613818,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {"activity":613818,"participants":[{"id":1001717,"user_id":null,"contact_id":4487,"lead_id":null},{"id":1001718,"user_id":261,"contact_id":null,"lead_id":null}]} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":613818,"team_id":2,"email":"[EMAIL]"} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [CrmActivityService] CRM matching completed {"activity_id":613818,"participants_processed":2,"exact_matches":1,"domain_matches":0,"best_match_found":true} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613818} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613818,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {"activity":613818,"remote_search":true,"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":613812,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36}} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613812} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613812,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Participants old state {"activity":613812,"participants":[{"id":1001705,"user_id":null,"contact_id":4487,"lead_id":null},{"id":1001706,"user_id":261,"contact_id":null,"lead_id":null}]} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":613812,"team_id":2,"email":"[EMAIL]"} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [CrmActivityService] CRM matching completed {"activity_id":613812,"participants_processed":2,"exact_matches":1,"domain_matches":0,"best_match_found":true} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613812} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613812,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {"activity":613812,"remote_search":true,"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":613807,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":4484,"account_id":243,"opportunity_id":276,"stage_id":36}} {"correlation_id":"499c94c1-2716-49a2-9cdf-d5eb84f68ac6","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613807} {"correlation_id":"499c94c1-2716-49a2-9cdf-d5eb84f68ac6","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613807,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"499c94c1-2716-49a2-9cdf-d5eb84f68ac6","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Participants old state {"activity":613807,"participants":[{"id":1001690,"user_id":253,"contact_id":null,"lead_id":null},{"id":1001691,"user_id":null,"contact_id":4484,"lead_id":null}]} {"correlation_id":"499c94c1-2716-49a2-9cdf-d5eb84f68ac6","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"499c94c1-2716-49a2-9cdf-d5eb84f68ac6","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"499c94c1-2716-49a2-9cdf-d5eb84f68ac6","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"499c94c1-2716-49a2-9cdf-d5eb84f68ac6","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"499c94c1-2716-49a2-9cdf-d5eb84f68ac6","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":613807,"team_id":2,"email":"[EMAIL]"} {"correlation_id":"499c94c1-2716-49a2-9cdf-d5eb84f68ac6","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: ProspectCache - Searching DB for opportunity by owner {"account_id"...
|
[{"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 Jiminny\\Exceptions;\n\nuse Throwable;\n\nclass RateLimitException extends RuntimeException\n{\n public function __construct(\n string $message = '',\n private readonly int $retryAfter = 1,\n ?Throwable $previous = null,\n ) {\n parent::__construct($message, 0, $previous);\n }\n\n public function getRetryAfter(): int\n {\n return max($this->retryAfter, 1);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Exceptions;\n\nuse Throwable;\n\nclass RateLimitException extends RuntimeException\n{\n public function __construct(\n string $message = '',\n private readonly int $retryAfter = 1,\n ?Throwable $previous = null,\n ) {\n parent::__construct($message, 0, $previous);\n }\n\n public function getRetryAfter(): int\n {\n return max($this->retryAfter, 1);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"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":"429","depth":4,"on_screen":true,"value":"429","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},{"role":"AXStaticText","text":"23/38","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","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":"454","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-11 11:17:21] local.NOTICE: Monitoring start {\"correlation_id\":\"885fde59-3852-4120-a620-af3da7ecce17\",\"trace_id\":\"4cc10f53-5d39-418d-8e98-fe53d9bbff5f\"}\n[2026-05-11 11:17:21] local.NOTICE: Monitoring end {\"correlation_id\":\"885fde59-3852-4120-a620-af3da7ecce17\",\"trace_id\":\"4cc10f53-5d39-418d-8e98-fe53d9bbff5f\"}\n[2026-05-11 11:17:34] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a773fb28-5a0c-4b8f-a1b5-d57e6b81db90\",\"trace_id\":\"fb6d8028-db7d-4ef2-b175-740f0a7b8b39\"}\n[2026-05-11 11:17:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"a773fb28-5a0c-4b8f-a1b5-d57e6b81db90\",\"trace_id\":\"fb6d8028-db7d-4ef2-b175-740f0a7b8b39\"}\n[2026-05-11 11:17:37] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":615092,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:37] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":615092} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:37] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":615092,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:37] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":615092,\"participants\":[{\"id\":1004102,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1004103,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:37] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:37] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:37] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [Hubspot] Failed to fetch contact {\"email\":\"nikolay.nikolov@jiminny.com\",\"reason\":\"[404] Client error: `GET https://api.hubapi.com/crm/v3/objects/contacts/nikolay.nikolov%40jiminny.com?properties=email%2Cfirstname%2Clastname%2Ccountry%2Cphone%2Cmobilephone%2Cjobtitle%2Chubspot_owner_id%2Cassociatedcompanyid%2Cphoto&archived=0&idProperty=email` resulted in a `404 Not Found` response\"} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [Prospect match] API returned empty result, caching the miss with empty prospect data {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.WARNING: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":1,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e16c1-c (truncated...)\n\"} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {\"job_class\":\"Jiminny\\\\Jobs\\\\Crm\\\\MatchActivityCrmData\",\"attempts\":1,\"retry_after\":1,\"delay\":4} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":614436,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614436} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614436,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":614436,\"participants\":[{\"id\":1002751,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1002752,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {\"job_class\":\"Jiminny\\\\Jobs\\\\Crm\\\\MatchActivityCrmData\",\"attempts\":1,\"retry_after\":1,\"delay\":3} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":614382,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614382} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614382,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":614382,\"participants\":[{\"id\":1002632,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1002633,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {\"job_class\":\"Jiminny\\\\Jobs\\\\Crm\\\\MatchActivityCrmData\",\"attempts\":1,\"retry_after\":1,\"delay\":1} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":614381,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614381} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614381,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":614381,\"participants\":[{\"id\":1002630,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1002631,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.WARNING: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":1,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e16c1-c (truncated...)\n\"} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {\"job_class\":\"Jiminny\\\\Jobs\\\\Crm\\\\MatchActivityCrmData\",\"attempts\":1,\"retry_after\":1,\"delay\":2} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":614378,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":6167,\"account_id\":null,\"opportunity_id\":null,\"stage_id\":null}} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614378} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614378,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":614378,\"participants\":[{\"id\":1002623,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1002624,\"user_id\":null,\"contact_id\":6167,\"lead_id\":null},{\"id\":1002625,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {\"job_class\":\"Jiminny\\\\Jobs\\\\Crm\\\\MatchActivityCrmData\",\"attempts\":1,\"retry_after\":1,\"delay\":3} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613840,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613840} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613840,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613840,\"participants\":[{\"id\":1001764,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001765,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":244,\"contact_id\":4487,\"owner_id\":261} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":244,\"contact_id\":4487,\"opportunity_id\":299} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613840,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613840,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613840} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613840,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613840,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613833,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613833} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613833,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613833,\"participants\":[{\"id\":1001750,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001751,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":1.0,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613833,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613833,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613833} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613833,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613833,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613827,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613827} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613827,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613827,\"participants\":[{\"id\":1001734,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001735,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613827,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613827,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613827} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613827,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613827,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613826,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613826} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613826,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613826,\"participants\":[{\"id\":1001732,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001733,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613826,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613826,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613826} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613826,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613826,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613820,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613820} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613820,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613820,\"participants\":[{\"id\":1001721,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001722,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613820,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613820,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613820} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613820,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613820,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613818,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613818} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613818,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613818,\"participants\":[{\"id\":1001717,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001718,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613818,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613818,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613818} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613818,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613818,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613812,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613812} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613812,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613812,\"participants\":[{\"id\":1001705,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001706,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613812,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613812,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613812} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613812,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613812,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613807,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4484,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613807} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613807,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613807,\"participants\":[{\"id\":1001690,\"user_id\":253,\"contact_id\":null,\"lead_id\":null},{\"id\":1001691,\"user_id\":null,\"contact_id\":4484,\"lead_id\":null}]} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613807,\"team_id\":2,\"email\":\"preslava.ivanova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":243,\"contact_id\":4484,\"owner_id\":253} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: ProspectCache - Fallback DB opportunity search {\"account_id\":243,\"contact_id\":4484} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":243,\"contact_id\":4484,\"opportunity_id\":276} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"tsvetomir.banovski@gmail.com\"} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613807,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613807} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613807,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613807,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4484,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613806,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34}} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613806} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613806,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613806,\"participants\":[{\"id\":1001688,\"user_id\":253,\"contact_id\":null,\"lead_id\":null},{\"id\":1001689,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null}]} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613806,\"team_id\":2,\"email\":\"preslava.ivanova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":244,\"contact_id\":4487,\"owner_id\":253} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: ProspectCache - Fallback DB opportunity search {\"account_id\":244,\"contact_id\":4487} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":244,\"contact_id\":4487,\"opportunity_id\":350} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613806,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613806} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613806,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613806,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613805,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34}} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613805} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613805,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613805,\"participants\":[{\"id\":1001686,\"user_id\":253,\"contact_id\":null,\"lead_id\":null},{\"id\":1001687,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null}]} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613805,\"team_id\":2,\"email\":\"preslava.ivanova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613805,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613805} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613805,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613805,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613698,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613698} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613698,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613698,\"participants\":[{\"id\":1001667,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001668,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613698,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613698,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613698} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613698,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613698,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613697,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613697} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613697,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613697,\"participants\":[{\"id\":1001665,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001666,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613697,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613697,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613697} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613697,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613697,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613696,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613696} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613696,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613696,\"participants\":[{\"id\":1001663,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001664,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613696,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613696,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613696} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613696,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613696,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613695,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613695} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613695,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613695,\"participants\":[{\"id\":1001661,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001662,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613695,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613695,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613695} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613695,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613695,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613694,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613694} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613694,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613694,\"participants\":[{\"id\":1001659,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001660,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613694,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613694,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613694} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613694,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613694,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613157,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34}} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613157} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613157,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613157,\"participants\":[{\"id\":1000746,\"user_id\":253,\"contact_id\":null,\"lead_id\":null},{\"id\":1000747,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null}]} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613157,\"team_id\":2,\"email\":\"preslava.ivanova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613157,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613157} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613157,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613157,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613156,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34}} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613156} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613156,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613156,\"participants\":[{\"id\":1000744,\"user_id\":253,\"contact_id\":null,\"lead_id\":null},{\"id\":1000745,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null}]} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613156,\"team_id\":2,\"email\":\"preslava.ivanova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613156,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613156} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613156,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613156,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"859a4ec6-5c81-4283-bb96-c3ebaf5ff599\",\"trace_id\":\"f8a2783e-c54a-4d43-8cf6-61594479b0e7\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613155,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34}} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613155} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613155,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613155,\"participants\":[{\"id\":1000742,\"user_id\":253,\"contact_id\":null,\"lead_id\":null},{\"id\":1000743,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null}]} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"859a4ec6-5c81-4283-bb96-c3ebaf5ff599\",\"trace_id\":\"f8a2783e-c54a-4d43-8cf6-61594479b0e7\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613155,\"team_id\":2,\"email\":\"preslava.ivanova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613155,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613155} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613155,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613155,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"859a4ec6-5c81-4283-bb96-c3ebaf5ff599\",\"trace_id\":\"f8a2783e-c54a-4d43-8cf6-61594479b0e7\"}\n[2026-05-11 11:17:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"859a4ec6-5c81-4283-bb96-c3ebaf5ff599\",\"trace_id\":\"f8a2783e-c54a-4d43-8cf6-61594479b0e7\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613130,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613130} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613130,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613130,\"participants\":[{\"id\":1000693,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1000694,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613130,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613130,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613130} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613130,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613130,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612924,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":165,\"stage_id\":89}} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612924} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612924,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612924,\"participants\":[{\"id\":1000290,\"user_id\":19,\"contact_id\":null,\"lead_id\":null},{\"id\":1000291,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612924,\"team_id\":2,\"email\":\"james.graham@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":69,\"contact_id\":97,\"owner_id\":19} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":69,\"contact_id\":97,\"opportunity_id\":165} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612924,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612924} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612924,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612924,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":165,\"stage_id\":89} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612923,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":165,\"stage_id\":89}} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612923} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612923,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612923,\"participants\":[{\"id\":1000288,\"user_id\":19,\"contact_id\":null,\"lead_id\":null},{\"id\":1000289,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612923,\"team_id\":2,\"email\":\"james.graham@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612923,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612923} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612923,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612923,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":165,\"stage_id\":89} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612922,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":165,\"stage_id\":89}} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612922} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612922,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612922,\"participants\":[{\"id\":1000286,\"user_id\":19,\"contact_id\":null,\"lead_id\":null},{\"id\":1000287,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612922,\"team_id\":2,\"email\":\"james.graham@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612922,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612922} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612922,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612922,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":165,\"stage_id\":89} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612847,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612847} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612847,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612847,\"participants\":[{\"id\":1000130,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1000131,\"user_id\":261,\"contact_id\":null,\"lead_id\":null},{\"id\":1000151,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null}]} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"email\",\"identifier\":\"adelina.petrova@jiminny.com\"} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:44] local.INFO: [Hubspot] Failed to fetch contact {\"email\":\"adelina.petrova@jiminny.com\",\"reason\":\"[404] Client error: `GET https://api.hubapi.com/crm/v3/objects/contacts/adelina.petrova%40jiminny.com?properties=email%2Cfirstname%2Clastname%2Ccountry%2Cphone%2Cmobilephone%2Cjobtitle%2Chubspot_owner_id%2Cassociatedcompanyid%2Cphoto&archived=0&idProperty=email` resulted in a `404 Not Found` response\"} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:44] local.INFO: [Prospect match] API returned empty result, caching the miss with empty prospect data {\"identifier_type\":\"email\",\"identifier\":\"adelina.petrova@jiminny.com\"} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:44] local.WARNING: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":1,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e16c1-d (truncated...)\n\"} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:44] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {\"job_class\":\"Jiminny\\\\Jobs\\\\Crm\\\\MatchActivityCrmData\",\"attempts\":1,\"retry_after\":1,\"delay\":5} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:44] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612822,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:44] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612822} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:44] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612822,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:44] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612822,\"participants\":[{\"id\":1000080,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1000081,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612822,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612822,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612822} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612822,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612822,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612819,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612819} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612819,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612819,\"participants\":[{\"id\":1000073,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1000074,\"user_id\":261,\"contact_id\":null,\"lead_id\":null},{\"id\":1000075,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:46] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:46] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:46] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:46] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:46] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612819,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:46] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"adelina.petrova@jiminny.com\"} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:46] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"adelina.petrova@jiminny.com\"} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:47] local.WARNING: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":1,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e16c1-e (truncated...)\n\"} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:47] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {\"job_class\":\"Jiminny\\\\Jobs\\\\Crm\\\\MatchActivityCrmData\",\"attempts\":1,\"retry_after\":1,\"delay\":4} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612673,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612673} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612673,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612673,\"participants\":[{\"id\":999993,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":999994,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612673,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612673,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612673} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612673,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:49] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612673,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:49] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612642,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:49] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612642} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:49] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612642,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:49] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612642,\"participants\":[{\"id\":999935,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":999936,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:49] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:49] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612642,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612642,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612642} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612642,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612642,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612598,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612598} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612598,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612598,\"participants\":[{\"id\":999857,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999858,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":243,\"contact_id\":4491,\"owner_id\":206} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: ProspectCache - Fallback DB opportunity search {\"account_id\":243,\"contact_id\":4491} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":243,\"contact_id\":4491,\"opportunity_id\":276} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612598,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612598,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612598} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612598,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612598,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612597,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612597} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612597,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612597,\"participants\":[{\"id\":999855,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999856,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612597,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:54] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612597,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:54] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612597} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:54] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612597,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:54] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612597,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612596,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612596} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612596,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612596,\"participants\":[{\"id\":999853,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999854,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612596,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612596,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612596} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612596,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612596,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612595,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612595} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612595,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612595,\"participants\":[{\"id\":999851,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999852,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612595,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612595,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612595} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612595,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612595,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612594,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612594} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612594,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612594,\"participants\":[{\"id\":999849,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999850,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612594,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612594,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612594} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612594,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612594,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612593,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612593} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612593,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612593,\"participants\":[{\"id\":999847,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999848,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612593,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612593,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612593} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612593,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612593,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612592,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612592} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612592,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612592,\"participants\":[{\"id\":999845,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999846,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612592,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612592,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612592} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612592,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612592,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612591,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612591} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612591,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612591,\"participants\":[{\"id\":999843,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999844,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612591,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612591,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612591} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612591,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612591,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612590,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612590} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612590,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612590,\"participants\":[{\"id\":999841,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999842,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612590,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612590,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612590} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612590,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612590,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612589,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612589} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612589,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612589,\"participants\":[{\"id\":999839,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999840,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612589,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612589,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612589} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612589,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612589,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612588,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612588} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612588,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612588,\"participants\":[{\"id\":999837,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999838,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612588,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612588,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612588} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612588,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612588,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":16.99,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:18:02] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612587,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612587} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612587,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612587,\"participants\":[{\"id\":999835,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999836,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612587,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612587,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612587} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612587,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612587,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612586,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612586} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612586,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612586,\"participants\":[{\"id\":999833,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999834,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612586,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612586,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612586} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612586,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612586,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:03] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612585,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:03] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612585} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:03] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612585,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:03] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612585,\"participants\":[{\"id\":999831,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999832,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:03] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:03] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612585,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612585,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612585} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612585,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612585,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612584,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612584} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:05] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612584,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:05] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612584,\"participants\":[{\"id\":999829,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999830,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:05] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:05] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:05] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:05] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612584,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612584,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612584} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612584,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612584,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612583,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612583} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612583,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612583,\"participants\":[{\"id\":999827,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999828,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:07] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:07] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:07] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:07] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:07] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:07] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612583,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:07] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612583,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:07] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612583} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:07] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612583,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:08] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612583,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612582,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612582} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612582,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612582,\"participants\":[{\"id\":999825,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999826,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612582,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612582,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612582} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612582,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:10] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612582,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:11] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612581,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:11] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612581} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:11] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612581,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:11] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612581,\"participants\":[{\"id\":999823,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999824,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:11] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":4.14,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:18:11] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:11] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:11] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:11] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:11] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:12] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612581,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:12] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612581,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:12] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612581} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:12] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612581,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:12] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612581,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612565,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612565} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612565,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612565,\"participants\":[{\"id\":999789,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999790,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"feff8215-75fe-40b2-916e-951435e048aa\",\"trace_id\":\"46d069ed-7c2b-4fdc-9679-9ec571a88271\"}\n[2026-05-11 11:18:15] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612565,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612565,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612565} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612565,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:16] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612565,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:16] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"feff8215-75fe-40b2-916e-951435e048aa\",\"trace_id\":\"46d069ed-7c2b-4fdc-9679-9ec571a88271\"}\n[2026-05-11 11:18:16] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612563,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34}} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:16] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612563} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:16] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612563,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:16] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612563,\"participants\":[{\"id\":999784,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999785,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null}]} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:17] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:17] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:17] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612563,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:17] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":244,\"contact_id\":4487,\"owner_id\":206} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:17] local.INFO: ProspectCache - Fallback DB opportunity search {\"account_id\":244,\"contact_id\":4487} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:17] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":244,\"contact_id\":4487,\"opportunity_id\":350} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:17] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"feff8215-75fe-40b2-916e-951435e048aa\",\"trace_id\":\"46d069ed-7c2b-4fdc-9679-9ec571a88271\"}\n[2026-05-11 11:18:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"feff8215-75fe-40b2-916e-951435e048aa\",\"trace_id\":\"46d069ed-7c2b-4fdc-9679-9ec571a88271\"}\n[2026-05-11 11:18:18] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:19] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612563,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:19] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612563} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:19] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612563,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:19] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612563,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:19] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":3.06,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:18:19] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"5a640073-717d-40da-ad67-be02e37c56a2\",\"trace_id\":\"46d069ed-7c2b-4fdc-9679-9ec571a88271\"}\n[2026-05-11 11:18:20] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612562,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:20] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612562} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:20] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612562,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:20] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612562,\"participants\":[{\"id\":999782,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":999783,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:20] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:20] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:20] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:20] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:20] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"email\",\"identifier\":\"447782589921@txt.staging.jiminny.com\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:21] local.INFO: [Hubspot] Failed to fetch contact {\"email\":\"447782589921@txt.staging.jiminny.com\",\"reason\":\"[404] Client error: `GET https://api.hubapi.com/crm/v3/objects/contacts/447782589921%40txt.staging.jiminny.com?properties=email%2Cfirstname%2Clastname%2Ccountry%2Cphone%2Cmobilephone%2Cjobtitle%2Chubspot_owner_id%2Cassociatedcompanyid%2Cphoto&archived=0&idProperty=email` resulted in a `404 Not Found` response\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:21] local.INFO: [Prospect match] API returned empty result, caching the miss with empty prospect data {\"identifier_type\":\"email\",\"identifier\":\"447782589921@txt.staging.jiminny.com\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:21] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.24,\"average_seconds_per_request\":0.24} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:22] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"447782589921@txt.staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:22] local.INFO: [Prospect match] Cache miss {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\",\"crm\":\"hubspot\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:22] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:22] local.INFO: [HubSpot] importAccount {\"crm_provider_id\":\"749766179\",\"config_id\":2} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:22] local.INFO: [HubSpot] CRM Search requested {\"request\":{\"filterGroups\":[{\"filters\":[{\"propertyName\":\"associations.company\",\"operator\":\"EQ\",\"value\":\"749766179\"},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedwon\",\"4040964\",\"59247967\"]},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedlost\",\"4040965\",\"59247968\"]}]}],\"sorts\":[{\"propertyName\":\"modifieddate\",\"direction\":\"DESCENDING\"}],\"properties\":[\"dealname\",\"amount\",\"hubspot_owner_id\",\"pipeline\",\"dealstage\",\"closedate\",\"deal_currency_code\"],\"limit\":200}} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:22] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":10,\"total_elapsed_seconds\":0.32,\"average_seconds_per_request\":0.32} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612562,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612562,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612562} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612562,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612562,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612561,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612561} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612561,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612561,\"participants\":[{\"id\":999780,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999781,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612561,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"email\",\"identifier\":\"447700174614.447782589921.OeREojLVnk@txt.staging.jiminny.com\"} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [Hubspot] Failed to fetch contact {\"email\":\"447700174614.447782589921.OeREojLVnk@txt.staging.jiminny.com\",\"reason\":\"[404] Client error: `GET https://api.hubapi.com/crm/v3/objects/contacts/447700174614.447782589921.OeREojLVnk%40txt.staging.jiminny.com?properties=email%2Cfirstname%2Clastname%2Ccountry%2Cphone%2Cmobilephone%2Cjobtitle%2Chubspot_owner_id%2Cassociatedcompanyid%2Cphoto&archived=0&idProperty=email` resulted in a `404 Not Found` response\"} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [Prospect match] API returned empty result, caching the miss with empty prospect data {\"identifier_type\":\"email\",\"identifier\":\"447700174614.447782589921.OeREojLVnk@txt.staging.jiminny.com\"} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"447700174614.447782589921.OeREojLVnk@txt.staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612561,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612561} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612561,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612561,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612560,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612560} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612560,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612560,\"participants\":[{\"id\":999778,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":999779,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"447782589921@txt.staging.jiminny.com\"} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"447782589921@txt.staging.jiminny.com\"} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"447782589921@txt.staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612560,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612560,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612560} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612560,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612560,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612559,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":1.89,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:18:26] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612559} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612559,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612559,\"participants\":[{\"id\":999776,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999777,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612559,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":69,\"contact_id\":97,\"owner_id\":206} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: ProspectCache - Fallback DB opportunity search {\"account_id\":69,\"contact_id\":97} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":69,\"contact_id\":97,\"opportunity_id\":5011} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612559,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612559} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612559,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612559,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612558,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612558} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612558,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612558,\"participants\":[{\"id\":999774,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999775,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612558,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612558,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612558} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612558,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612558,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612557,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612557} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612557,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612557,\"participants\":[{\"id\":999772,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999773,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612557,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612557,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612557} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612557,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612557,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612556,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612556} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612556,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612556,\"participants\":[{\"id\":999770,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999771,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612556,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612556,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612556} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612556,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612556,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612555,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612555} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612555,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612555,\"participants\":[{\"id\":999768,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999769,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612555,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612555,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612555} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612555,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612555,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612554,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612554} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612554,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612554,\"participants\":[{\"id\":999766,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999767,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612554,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612554,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612554} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612554,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612554,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612553,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612553} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612553,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612553,\"participants\":[{\"id\":999764,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999765,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612553,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612553,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612553} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612553,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612553,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612552,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612552} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612552,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612552,\"participants\":[{\"id\":999762,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999763,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612552,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612552,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612552} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612552,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612552,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612551,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612551} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612551,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612551,\"participants\":[{\"id\":999760,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999761,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612551,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612551,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612551} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612551,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612551,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612550,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612550} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612550,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612550,\"participants\":[{\"id\":999758,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999759,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612550,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612550,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612550} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612550,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612550,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612549,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612549} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612549,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612549,\"participants\":[{\"id\":999756,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999757,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612549,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612549,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612549} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612549,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612549,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612365,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612365} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612365,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612365,\"participants\":[{\"id\":999563,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999564,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":243,\"contact_id\":4491,\"owner_id\":206} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: ProspectCache - Fallback DB opportunity search {\"account_id\":243,\"contact_id\":4491} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":243,\"contact_id\":4491,\"opportunity_id\":276} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612365,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612365,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612365} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612365,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612365,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612360,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612360} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612360,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612360,\"participants\":[{\"id\":999552,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999553,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999565,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612360,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.29,\"average_seconds_per_request\":0.29} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612360,\"participants_processed\":3,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612360} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612360,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612360,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612340,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612340} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612340,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612340,\"participants\":[{\"id\":999516,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999517,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999518,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":999519,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612340,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.34,\"average_seconds_per_request\":0.34} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612340,\"participants_processed\":4,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612340} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612340,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612340,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":0.75,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:18:32] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612339,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612339} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612339,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612339,\"participants\":[{\"id\":999514,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999515,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999540,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612339,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612339,\"participants_processed\":3,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612339} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612339,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612339,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612336,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612336} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612336,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612336,\"participants\":[{\"id\":999508,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999509,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999512,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":999513,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612336,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612336,\"participants_processed\":4,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612336} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612336,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612336,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612183,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612183} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612183,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612183,\"participants\":[{\"id\":999227,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":999228,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":244,\"contact_id\":4487,\"owner_id\":261} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":244,\"contact_id\":4487,\"opportunity_id\":299} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612183,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612183,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612183} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612183,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612183,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612182,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612182} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612182,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612182,\"participants\":[{\"id\":999225,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":999226,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612182,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612182,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612182} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612182,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612182,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612181,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612181} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612181,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612181,\"participants\":[{\"id\":999223,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":999224,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612181,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612181,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612181} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612181,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612181,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612180,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612180} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612180,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612180,\"participants\":[{\"id\":999221,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":999222,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612180,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612180,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612180} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612180,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612180,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":611455,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":611455} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":611455,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":611455,\"participants\":[{\"id\":997961,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997962,\"user_id\":1460,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [Hubspot] Failed to fetch contact {\"email\":\"support@staging.jiminny.com\",\"reason\":\"[404] Client error: `GET https://api.hubapi.com/crm/v3/objects/contacts/support%40staging.jiminny.com?properties=email%2Cfirstname%2Clastname%2Ccountry%2Cphone%2Cmobilephone%2Cjobtitle%2Chubspot_owner_id%2Cassociatedcompanyid%2Cphoto&archived=0&idProperty=email` resulted in a `404 Not Found` response\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [Prospect match] API returned empty result, caching the miss with empty prospect data {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.23,\"average_seconds_per_request\":0.23} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [Prospect match] Cache miss {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\",\"crm\":\"hubspot\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:35] local.INFO: [HubSpot] importAccount {\"crm_provider_id\":\"749766179\",\"config_id\":2} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:35] local.INFO: [HubSpot] CRM Search requested {\"request\":{\"filterGroups\":[{\"filters\":[{\"propertyName\":\"associations.company\",\"operator\":\"EQ\",\"value\":\"749766179\"},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedwon\",\"4040964\",\"59247967\"]},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedlost\",\"4040965\",\"59247968\"]}]}],\"sorts\":[{\"propertyName\":\"modifieddate\",\"direction\":\"DESCENDING\"}],\"properties\":[\"dealname\",\"amount\",\"hubspot_owner_id\",\"pipeline\",\"dealstage\",\"closedate\",\"deal_currency_code\"],\"limit\":200}} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:35] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":10,\"total_elapsed_seconds\":0.27,\"average_seconds_per_request\":0.27} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":611455,\"team_id\":2,\"email\":\"aneliya.angelova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":611455,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":611455} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":611455,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":611455,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":611451,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":611451} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":611451,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":611451,\"participants\":[{\"id\":997955,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997956,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [Hubspot] Failed to fetch contact {\"email\":\"support@staging.jiminny.com\",\"reason\":\"[404] Client error: `GET https://api.hubapi.com/crm/v3/objects/contacts/support%40staging.jiminny.com?properties=email%2Cfirstname%2Clastname%2Ccountry%2Cphone%2Cmobilephone%2Cjobtitle%2Chubspot_owner_id%2Cassociatedcompanyid%2Cphoto&archived=0&idProperty=email` resulted in a `404 Not Found` response\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [Prospect match] API returned empty result, caching the miss with empty prospect data {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:37] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.25,\"average_seconds_per_request\":0.25} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:37] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:37] local.INFO: [Prospect match] Cache miss {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\",\"crm\":\"hubspot\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:37] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:37] local.INFO: [HubSpot] importAccount {\"crm_provider_id\":\"749766179\",\"config_id\":2} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:37] local.INFO: [HubSpot] CRM Search requested {\"request\":{\"filterGroups\":[{\"filters\":[{\"propertyName\":\"associations.company\",\"operator\":\"EQ\",\"value\":\"749766179\"},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedwon\",\"4040964\",\"59247967\"]},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedlost\",\"4040965\",\"59247968\"]}]}],\"sorts\":[{\"propertyName\":\"modifieddate\",\"direction\":\"DESCENDING\"}],\"properties\":[\"dealname\",\"amount\",\"hubspot_owner_id\",\"pipeline\",\"dealstage\",\"closedate\",\"deal_currency_code\"],\"limit\":200}} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:38] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":10,\"total_elapsed_seconds\":0.44,\"average_seconds_per_request\":0.44} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":611451,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":3.16,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:18:40] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":611451,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":611451} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":611451,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":611451,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":611087,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":611087} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":611087,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":611087,\"participants\":[{\"id\":997368,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997369,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":611087,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":611087,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":611087} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":611087,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":611087,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":611076,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":611076} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":611076,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":611076,\"participants\":[{\"id\":997346,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997347,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":611076,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":611076,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":611076} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":611076,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":611076,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610935,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610935} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610935,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610935,\"participants\":[{\"id\":997141,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997142,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610935,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610935,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610935} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610935,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610935,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610915,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610915} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610915,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610915,\"participants\":[{\"id\":997104,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997105,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610915,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610915,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610915} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610915,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610915,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610900,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610900} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610900,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610900,\"participants\":[{\"id\":997081,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997082,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610900,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610900,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610900} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610900,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610900,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610885,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610885} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610885,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610885,\"participants\":[{\"id\":997051,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997052,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610885,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610885,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610885} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610885,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610885,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610878,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610878} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610878,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610878,\"participants\":[{\"id\":997035,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997036,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610878,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610878,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610878} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610878,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610878,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610874,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610874} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610874,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610874,\"participants\":[{\"id\":997025,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997026,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610874,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610874,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610874} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610874,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610874,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610867,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610867} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610867,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610867,\"participants\":[{\"id\":997011,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997012,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610867,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610867,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610867} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610867,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610867,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610764,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610764} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610764,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610764,\"participants\":[{\"id\":996951,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996952,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610764,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610764,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610764} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610764,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610764,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610617,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610617} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610617,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610617,\"participants\":[{\"id\":996641,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996642,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610617,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610617,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610617} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610617,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610617,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610539,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610539} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610539,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610539,\"participants\":[{\"id\":996485,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996486,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610539,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610539,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610539} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610539,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610539,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":0.4,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610528,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610528} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610528,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610528,\"participants\":[{\"id\":996463,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996464,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610528,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610528,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610528} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610528,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610528,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610506,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610506} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610506,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610506,\"participants\":[{\"id\":996419,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996420,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610506,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610506,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610506} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610506,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610506,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610497,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610497} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610497,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610497,\"participants\":[{\"id\":996401,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996402,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610497,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610497,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610497} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610497,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610497,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610490,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610490} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610490,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610490,\"participants\":[{\"id\":996385,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996386,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610490,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610490,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610490} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610490,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610490,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610470,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610470} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610470,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610470,\"participants\":[{\"id\":996369,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996370,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610470,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610470,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610470} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610470,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610470,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610462,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610462} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610462,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610462,\"participants\":[{\"id\":996353,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996354,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610462,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610462,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610462} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610462,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610462,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610451,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610451} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610451,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610451,\"participants\":[{\"id\":996340,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996341,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610451,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610451,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610451} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610451,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610451,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610438,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610438} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610438,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610438,\"participants\":[{\"id\":996320,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996321,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610438,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610438,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610438} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610438,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610438,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610426,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610426} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610426,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610426,\"participants\":[{\"id\":996306,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996307,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610426,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610426,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610426} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610426,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610426,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610403,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610403} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610403,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610403,\"participants\":[{\"id\":996282,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996283,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610403,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610403,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610403} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610403,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610403,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610400,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34}} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610400} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610400,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610400,\"participants\":[{\"id\":996275,\"user_id\":1460,\"contact_id\":null,\"lead_id\":null},{\"id\":996276,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":996277,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null}]} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610400,\"team_id\":2,\"email\":\"aneliya.angelova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610400,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":244,\"contact_id\":4487,\"owner_id\":1460} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: ProspectCache - Fallback DB opportunity search {\"account_id\":244,\"contact_id\":4487} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":244,\"contact_id\":4487,\"opportunity_id\":350} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610400,\"participants_processed\":3,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610400} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610400,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610400,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":614382,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614382} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614382,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":614382,\"participants\":[{\"id\":1002632,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1002633,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [Hubspot] Failed to fetch contact {\"email\":\"nikolay.nikolov@jiminny.com\",\"reason\":\"[404] Client error: `GET https://api.hubapi.com/crm/v3/objects/contacts/nikolay.nikolov%40jiminny.com?properties=email%2Cfirstname%2Clastname%2Ccountry%2Cphone%2Cmobilephone%2Cjobtitle%2Chubspot_owner_id%2Cassociatedcompanyid%2Cphoto&archived=0&idProperty=email` resulted in a `404 Not Found` response\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [Prospect match] API returned empty result, caching the miss with empty prospect data {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:49] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.51,\"average_seconds_per_request\":0.51} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:49] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"nikolay.nikolov@jiminny.com\",\"domain\":\"jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:49] local.INFO: [Prospect match] Cache miss {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\",\"crm\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:49] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:49] local.INFO: [HubSpot] importAccount {\"crm_provider_id\":\"749766179\",\"config_id\":2} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:49] local.INFO: [HubSpot] CRM Search requested {\"request\":{\"filterGroups\":[{\"filters\":[{\"propertyName\":\"associations.company\",\"operator\":\"EQ\",\"value\":\"749766179\"},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedwon\",\"4040964\",\"59247967\"]},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedlost\",\"4040965\",\"59247968\"]}]}],\"sorts\":[{\"propertyName\":\"modifieddate\",\"direction\":\"DESCENDING\"}],\"properties\":[\"dealname\",\"amount\",\"hubspot_owner_id\",\"pipeline\",\"dealstage\",\"closedate\",\"deal_currency_code\"],\"limit\":200}} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:49] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":10,\"total_elapsed_seconds\":0.35,\"average_seconds_per_request\":0.35} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:50] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":614382,\"team_id\":2,\"email\":\"nikolay.nikolov@jiminny.onmicrosoft.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:50] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":614382,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614382} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614382,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":614382,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":614381,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614381} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614381,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":614381,\"participants\":[{\"id\":1002630,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1002631,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"nikolay.nikolov@jiminny.com\",\"domain\":\"jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":614381,\"team_id\":2,\"email\":\"nikolay.nikolov@jiminny.onmicrosoft.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":614381,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614381} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614381,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":614381,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":615092,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":615092} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":615092,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":615092,\"participants\":[{\"id\":1004102,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1004103,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"nikolay.nikolov@jiminny.com\",\"domain\":\"jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":615092,\"team_id\":2,\"email\":\"nikolay.nikolov@jiminny.onmicrosoft.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":615092,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":615092} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":615092,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":615092,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":614436,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614436} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614436,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":614436,\"participants\":[{\"id\":1002751,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1002752,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"nikolay.nikolov@jiminny.com\",\"domain\":\"jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":614436,\"team_id\":2,\"email\":\"nikolay.nikolov@jiminny.onmicrosoft.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":614436,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614436} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614436,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":614436,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":614378,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":6167,\"account_id\":null,\"opportunity_id\":null,\"stage_id\":null}} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614378} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614378,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":614378,\"participants\":[{\"id\":1002623,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1002624,\"user_id\":null,\"contact_id\":6167,\"lead_id\":null},{\"id\":1002625,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"nikolay.nikolov@jiminny.com\",\"domain\":\"jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"nmalchev@gmail.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":614378,\"team_id\":2,\"email\":\"nikolay.nikolov@jiminny.onmicrosoft.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":614378,\"participants_processed\":3,\"exact_matches\":1,\"domain_matches\":1,\"best_match_found\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614378} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614378,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":614378,\"remote_search\":true,\"lead_id\":null,\"contact_id\":6167,\"account_id\":null,\"opportunity_id\":null,\"stage_id\":null} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612847,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612847} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612847,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612847,\"participants\":[{\"id\":1000130,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1000131,\"user_id\":261,\"contact_id\":null,\"lead_id\":null},{\"id\":1000151,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null}]} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"email\",\"identifier\":\"adelina.petrova@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":0.84,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:18:51] local.INFO: [Hubspot] Failed to fetch contact {\"email\":\"adelina.petrova@jiminny.com\",\"reason\":\"[404] Client error: `GET https://api.hubapi.com/crm/v3/objects/contacts/adelina.petrova%40jiminny.com?properties=email%2Cfirstname%2Clastname%2Ccountry%2Cphone%2Cmobilephone%2Cjobtitle%2Chubspot_owner_id%2Cassociatedcompanyid%2Cphoto&archived=0&idProperty=email` resulted in a `404 Not Found` response\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [Prospect match] API returned empty result, caching the miss with empty prospect data {\"identifier_type\":\"email\",\"identifier\":\"adelina.petrova@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:52] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.28,\"average_seconds_per_request\":0.28} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:52] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"adelina.petrova@jiminny.com\",\"domain\":\"jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:52] local.INFO: [Prospect match] Cache miss {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\",\"crm\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:52] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:52] local.INFO: [HubSpot] importAccount {\"crm_provider_id\":\"749766179\",\"config_id\":2} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:52] local.INFO: [HubSpot] CRM Search requested {\"request\":{\"filterGroups\":[{\"filters\":[{\"propertyName\":\"associations.company\",\"operator\":\"EQ\",\"value\":\"749766179\"},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedwon\",\"4040964\",\"59247967\"]},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedlost\",\"4040965\",\"59247968\"]}]}],\"sorts\":[{\"propertyName\":\"modifieddate\",\"direction\":\"DESCENDING\"}],\"properties\":[\"dealname\",\"amount\",\"hubspot_owner_id\",\"pipeline\",\"dealstage\",\"closedate\",\"deal_currency_code\"],\"limit\":200}} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:53] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":10,\"total_elapsed_seconds\":0.43,\"average_seconds_per_request\":0.43} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:53] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612847,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:53] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:53] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612847,\"participants_processed\":3,\"exact_matches\":1,\"domain_matches\":1,\"best_match_found\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:54] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612847} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:54] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612847,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:54] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612847,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:54] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612819,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612819} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612819,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612819,\"participants\":[{\"id\":1000073,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1000074,\"user_id\":261,\"contact_id\":null,\"lead_id\":null},{\"id\":1000075,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612819,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"adelina.petrova@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"adelina.petrova@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"adelina.petrova@jiminny.com\",\"domain\":\"jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612819,\"participants_processed\":3,\"exact_matches\":1,\"domain_matches\":1,\"best_match_found\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612819} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612819,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612819,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:57] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":0.25,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:19:07] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"70d16739-7654-4185-99cb-49559aafc660\",\"trace_id\":\"d100f21a-5975-471a-b245-90b25b177c8f\"}\n[2026-05-11 11:19:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"70d16739-7654-4185-99cb-49559aafc660\",\"trace_id\":\"d100f21a-5975-471a-b245-90b25b177c8f\"}\n[2026-05-11 11:19:07] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"70d16739-7654-4185-99cb-49559aafc660\",\"trace_id\":\"d100f21a-5975-471a-b245-90b25b177c8f\"}\n[2026-05-11 11:19:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"91df8068-6c15-4614-947e-90f48574662c\",\"trace_id\":\"a9a86198-7521-4c0c-a89e-d23b34f2f8bf\"}\n[2026-05-11 11:19:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"91df8068-6c15-4614-947e-90f48574662c\",\"trace_id\":\"a9a86198-7521-4c0c-a89e-d23b34f2f8bf\"}\n[2026-05-11 11:19:15] local.NOTICE: Monitoring start {\"correlation_id\":\"6fae005c-3fcd-4718-86b0-f08f140f889c\",\"trace_id\":\"233ad400-a3ad-4093-8660-9e477cd6ca8f\"}\n[2026-05-11 11:19:15] local.NOTICE: Monitoring end {\"correlation_id\":\"6fae005c-3fcd-4718-86b0-f08f140f889c\",\"trace_id\":\"233ad400-a3ad-4093-8660-9e477cd6ca8f\"}\n[2026-05-11 11:19:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08b79017-e665-425f-8048-21f93b1abf3b\",\"trace_id\":\"bb7a7ea5-30d3-4a13-9c3c-84bc1f9c26e7\"}\n[2026-05-11 11:19:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08b79017-e665-425f-8048-21f93b1abf3b\",\"trace_id\":\"bb7a7ea5-30d3-4a13-9c3c-84bc1f9c26e7\"}\n[2026-05-11 11:19:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"0c31163b-b05f-4d3f-9a66-a2ce01d94010\",\"trace_id\":\"3dfb6352-28a3-4c77-b6ff-a11e0a7821a0\"}\n[2026-05-11 11:19:21] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"0c31163b-b05f-4d3f-9a66-a2ce01d94010\",\"trace_id\":\"3dfb6352-28a3-4c77-b6ff-a11e0a7821a0\"}\n[2026-05-11 11:19:22] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"0c31163b-b05f-4d3f-9a66-a2ce01d94010\",\"trace_id\":\"3dfb6352-28a3-4c77-b6ff-a11e0a7821a0\"}\n[2026-05-11 11:19:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"0c31163b-b05f-4d3f-9a66-a2ce01d94010\",\"trace_id\":\"3dfb6352-28a3-4c77-b6ff-a11e0a7821a0\"}\n[2026-05-11 11:20:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cb3a4a64-b00b-4f94-9e00-c190cd7a7a42\",\"trace_id\":\"acd43b75-f255-471f-9563-f03de03c7e23\"}\n[2026-05-11 11:20:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"cb3a4a64-b00b-4f94-9e00-c190cd7a7a42\",\"trace_id\":\"acd43b75-f255-471f-9563-f03de03c7e23\"}\n[2026-05-11 11:20:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cb3a4a64-b00b-4f94-9e00-c190cd7a7a42\",\"trace_id\":\"acd43b75-f255-471f-9563-f03de03c7e23\"}\n[2026-05-11 11:20:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8ab6728e-9079-4166-bf97-fed4fb2ac7de\",\"trace_id\":\"508ecd6c-81db-47d4-8fad-d40b1e55cff3\"}\n[2026-05-11 11:20:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"8ab6728e-9079-4166-bf97-fed4fb2ac7de\",\"trace_id\":\"508ecd6c-81db-47d4-8fad-d40b1e55cff3\"}\n[2026-05-11 11:20:13] local.NOTICE: Monitoring start {\"correlation_id\":\"98b2a767-ff2a-4f82-866f-bf7dad58fe13\",\"trace_id\":\"ecb25ade-8dda-4d47-8bce-6b84e3c8fd0c\"}\n[2026-05-11 11:20:13] local.NOTICE: Monitoring end {\"correlation_id\":\"98b2a767-ff2a-4f82-866f-bf7dad58fe13\",\"trace_id\":\"ecb25ade-8dda-4d47-8bce-6b84e3c8fd0c\"}\n[2026-05-11 11:20:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"05f19e62-48e4-4c36-9577-648a2dd54abd\",\"trace_id\":\"e3d3acd1-5c23-4f37-9566-32a0cbd7a4eb\"}\n[2026-05-11 11:20:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"05f19e62-48e4-4c36-9577-648a2dd54abd\",\"trace_id\":\"e3d3acd1-5c23-4f37-9566-32a0cbd7a4eb\"}\n[2026-05-11 11:20:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d5c19bc5-1a17-4b6d-9f62-a6715a8005c9\",\"trace_id\":\"451385cf-1bcd-4e06-8412-e5d197f5f567\"}\n[2026-05-11 11:20:18] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d5c19bc5-1a17-4b6d-9f62-a6715a8005c9\",\"trace_id\":\"451385cf-1bcd-4e06-8412-e5d197f5f567\"}\n[2026-05-11 11:20:18] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d5c19bc5-1a17-4b6d-9f62-a6715a8005c9\",\"trace_id\":\"451385cf-1bcd-4e06-8412-e5d197f5f567\"}\n[2026-05-11 11:20:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d5c19bc5-1a17-4b6d-9f62-a6715a8005c9\",\"trace_id\":\"451385cf-1bcd-4e06-8412-e5d197f5f567\"}\n[2026-05-11 11:20:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a01c4c40-1c1e-4865-be1f-0aa63b4fd1b9\",\"trace_id\":\"cba182ec-cbe6-4d53-b1c6-253546138cc8\"}\n[2026-05-11 11:20:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-11 11:18:00, 2026-05-11 11:20:00] {\"correlation_id\":\"a01c4c40-1c1e-4865-be1f-0aa63b4fd1b9\",\"trace_id\":\"cba182ec-cbe6-4d53-b1c6-253546138cc8\"}\n[2026-05-11 11:20:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-11 11:18:00, 2026-05-11 11:20:00] {\"correlation_id\":\"a01c4c40-1c1e-4865-be1f-0aa63b4fd1b9\",\"trace_id\":\"cba182ec-cbe6-4d53-b1c6-253546138cc8\"}\n[2026-05-11 11:20:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"a01c4c40-1c1e-4865-be1f-0aa63b4fd1b9\",\"trace_id\":\"cba182ec-cbe6-4d53-b1c6-253546138cc8\"}\n[2026-05-11 11:20:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b599f338-6a44-44d5-9f81-6fa300c4ea1b\",\"trace_id\":\"c7645418-4758-4410-83f2-8fe71ebf2ec2\"}\n[2026-05-11 11:20:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b599f338-6a44-44d5-9f81-6fa300c4ea1b\",\"trace_id\":\"c7645418-4758-4410-83f2-8fe71ebf2ec2\"}\n[2026-05-11 11:20:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3c9d7674-d005-4372-8a60-2e8ecb587584\",\"trace_id\":\"22a0bdee-d653-4113-963c-043a68a4a8be\"}\n[2026-05-11 11:20:29] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"3c9d7674-d005-4372-8a60-2e8ecb587584\",\"trace_id\":\"22a0bdee-d653-4113-963c-043a68a4a8be\"}\n[2026-05-11 11:20:31] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"1453203b-bac8-47ba-ac62-6369ac533fc2\",\"trace_id\":\"f176800e-9da8-4580-a332-56fa3402dbb7\"}\n[2026-05-11 11:20:31] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"1453203b-bac8-47ba-ac62-6369ac533fc2\",\"trace_id\":\"f176800e-9da8-4580-a332-56fa3402dbb7\"}\n[2026-05-11 11:20:31] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"1453203b-bac8-47ba-ac62-6369ac533fc2\",\"trace_id\":\"f176800e-9da8-4580-a332-56fa3402dbb7\"}\n[2026-05-11 11:20:33] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2310f110-1f7e-4a28-b0c3-e5f8fc72688f\",\"trace_id\":\"9d6e8217-2f4e-4b23-8f36-8538f57064d9\"}\n[2026-05-11 11:20:33] local.INFO: Running conference:monitor:start command for activities in (2026-05-11 11:10:00, 2026-05-11 11:15:00] {\"correlation_id\":\"2310f110-1f7e-4a28-b0c3-e5f8fc72688f\",\"trace_id\":\"9d6e8217-2f4e-4b23-8f36-8538f57064d9\"}\n[2026-05-11 11:20:33] local.INFO: [conference:monitor:start] No activities found in (2026-05-11 11:10:00, 2026-05-11 11:15:00] {\"correlation_id\":\"2310f110-1f7e-4a28-b0c3-e5f8fc72688f\",\"trace_id\":\"9d6e8217-2f4e-4b23-8f36-8538f57064d9\"}\n[2026-05-11 11:20:33] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2310f110-1f7e-4a28-b0c3-e5f8fc72688f\",\"trace_id\":\"9d6e8217-2f4e-4b23-8f36-8538f57064d9\"}\n[2026-05-11 11:20:37] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"48a2dc23-76e1-4b34-b8a7-a7a957c71373\",\"trace_id\":\"b1788ca3-54cf-4031-b198-102838446996\"}\n[2026-05-11 11:20:37] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"11:15\",\"to\":\"11:20\"} {\"correlation_id\":\"48a2dc23-76e1-4b34-b8a7-a7a957c71373\",\"trace_id\":\"b1788ca3-54cf-4031-b198-102838446996\"}\n[2026-05-11 11:20:38] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"01:10\",\"to\":\"01:15\"} {\"correlation_id\":\"48a2dc23-76e1-4b34-b8a7-a7a957c71373\",\"trace_id\":\"b1788ca3-54cf-4031-b198-102838446996\"}\n[2026-05-11 11:20:38] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"48a2dc23-76e1-4b34-b8a7-a7a957c71373\",\"trace_id\":\"b1788ca3-54cf-4031-b198-102838446996\"}\n[2026-05-11 11:20:41] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.ERROR: Failed to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.ERROR: Failed to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:43] local.ERROR: Failed to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:43] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"jiminny:transcription:retry-failed\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"28cf48be-a629-420c-a0a4-0d20fbd05838\",\"trace_id\":\"4fdaba19-5d8e-45db-a600-da048c8066fb\"}\n[2026-05-11 11:20:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6a6c06af-94cf-46bf-976e-55e401b3a588\",\"trace_id\":\"338c3b84-fc5a-404b-bed6-97341331ae68\"}\n[2026-05-11 11:20:48] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"954d156d-8a4f-4592-a046-e16c5dd7d3bf\",\"trace_id\":\"ecc7aeb5-a4e6-4a0d-9ebd-4aeb260f5d55\"}\n[2026-05-11 11:20:48] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":60.0} {\"correlation_id\":\"954d156d-8a4f-4592-a046-e16c5dd7d3bf\",\"trace_id\":\"ecc7aeb5-a4e6-4a0d-9ebd-4aeb260f5d55\"}\n[2026-05-11 11:20:48] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-11T11:22:48.807561Z\"} {\"correlation_id\":\"954d156d-8a4f-4592-a046-e16c5dd7d3bf\",\"trace_id\":\"ecc7aeb5-a4e6-4a0d-9ebd-4aeb260f5d55\"}\n[2026-05-11 11:20:48] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"954d156d-8a4f-4592-a046-e16c5dd7d3bf\",\"trace_id\":\"ecc7aeb5-a4e6-4a0d-9ebd-4aeb260f5d55\"}\n[2026-05-11 11:20:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"jiminny:transcription:retry-failed\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"28cf48be-a629-420c-a0a4-0d20fbd05838\",\"trace_id\":\"4fdaba19-5d8e-45db-a600-da048c8066fb\"}\n[2026-05-11 11:20:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6a6c06af-94cf-46bf-976e-55e401b3a588\",\"trace_id\":\"338c3b84-fc5a-404b-bed6-97341331ae68\"}\n[2026-05-11 11:20:49] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"954d156d-8a4f-4592-a046-e16c5dd7d3bf\",\"trace_id\":\"ecc7aeb5-a4e6-4a0d-9ebd-4aeb260f5d55\"}\n[2026-05-11 11:20:49] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"954d156d-8a4f-4592-a046-e16c5dd7d3bf\",\"trace_id\":\"ecc7aeb5-a4e6-4a0d-9ebd-4aeb260f5d55\"}\n[2026-05-11 11:20:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c8d52370-b908-428c-b973-699db0be2136\",\"trace_id\":\"fabc1f54-e263-4ba0-b8ff-324f62e84f1f\"}\n[2026-05-11 11:20:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c8d52370-b908-428c-b973-699db0be2136\",\"trace_id\":\"fabc1f54-e263-4ba0-b8ff-324f62e84f1f\"}\n[2026-05-11 11:20:54] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"954d156d-8a4f-4592-a046-e16c5dd7d3bf\",\"trace_id\":\"ecc7aeb5-a4e6-4a0d-9ebd-4aeb260f5d55\"}\n[2026-05-11 11:20:56] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"de84a4c9-d2c5-4950-8c2d-f400cee667bf\",\"trace_id\":\"223fd9b2-ed24-4083-98cd-1bc4040dbbd1\"}\n[2026-05-11 11:20:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"de84a4c9-d2c5-4950-8c2d-f400cee667bf\",\"trace_id\":\"223fd9b2-ed24-4083-98cd-1bc4040dbbd1\"}\n[2026-05-11 11:20:59] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"954d156d-8a4f-4592-a046-e16c5dd7d3bf\",\"trace_id\":\"ecc7aeb5-a4e6-4a0d-9ebd-4aeb260f5d55\"}","depth":4,"on_screen":true,"value":"[2026-05-11 11:17:21] local.NOTICE: Monitoring start {\"correlation_id\":\"885fde59-3852-4120-a620-af3da7ecce17\",\"trace_id\":\"4cc10f53-5d39-418d-8e98-fe53d9bbff5f\"}\n[2026-05-11 11:17:21] local.NOTICE: Monitoring end {\"correlation_id\":\"885fde59-3852-4120-a620-af3da7ecce17\",\"trace_id\":\"4cc10f53-5d39-418d-8e98-fe53d9bbff5f\"}\n[2026-05-11 11:17:34] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a773fb28-5a0c-4b8f-a1b5-d57e6b81db90\",\"trace_id\":\"fb6d8028-db7d-4ef2-b175-740f0a7b8b39\"}\n[2026-05-11 11:17:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"a773fb28-5a0c-4b8f-a1b5-d57e6b81db90\",\"trace_id\":\"fb6d8028-db7d-4ef2-b175-740f0a7b8b39\"}\n[2026-05-11 11:17:37] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":615092,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:37] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":615092} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:37] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":615092,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:37] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":615092,\"participants\":[{\"id\":1004102,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1004103,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:37] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:37] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:37] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [Hubspot] Failed to fetch contact {\"email\":\"nikolay.nikolov@jiminny.com\",\"reason\":\"[404] Client error: `GET https://api.hubapi.com/crm/v3/objects/contacts/nikolay.nikolov%40jiminny.com?properties=email%2Cfirstname%2Clastname%2Ccountry%2Cphone%2Cmobilephone%2Cjobtitle%2Chubspot_owner_id%2Cassociatedcompanyid%2Cphoto&archived=0&idProperty=email` resulted in a `404 Not Found` response\"} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [Prospect match] API returned empty result, caching the miss with empty prospect data {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.WARNING: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":1,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e16c1-c (truncated...)\n\"} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {\"job_class\":\"Jiminny\\\\Jobs\\\\Crm\\\\MatchActivityCrmData\",\"attempts\":1,\"retry_after\":1,\"delay\":4} {\"correlation_id\":\"01554272-3758-416d-bcd8-0b07cf17fce3\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":614436,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614436} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614436,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":614436,\"participants\":[{\"id\":1002751,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1002752,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:38] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {\"job_class\":\"Jiminny\\\\Jobs\\\\Crm\\\\MatchActivityCrmData\",\"attempts\":1,\"retry_after\":1,\"delay\":3} {\"correlation_id\":\"6f97c580-31f1-4723-80d8-b1046a615d37\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":614382,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614382} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614382,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":614382,\"participants\":[{\"id\":1002632,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1002633,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {\"job_class\":\"Jiminny\\\\Jobs\\\\Crm\\\\MatchActivityCrmData\",\"attempts\":1,\"retry_after\":1,\"delay\":1} {\"correlation_id\":\"80fe8576-047a-495f-b42a-d75cb83d9591\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":614381,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614381} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614381,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":614381,\"participants\":[{\"id\":1002630,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1002631,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.WARNING: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":1,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e16c1-c (truncated...)\n\"} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {\"job_class\":\"Jiminny\\\\Jobs\\\\Crm\\\\MatchActivityCrmData\",\"attempts\":1,\"retry_after\":1,\"delay\":2} {\"correlation_id\":\"55cd98de-2b2f-4dd6-b0d5-36af698ea32d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":614378,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":6167,\"account_id\":null,\"opportunity_id\":null,\"stage_id\":null}} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614378} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614378,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":614378,\"participants\":[{\"id\":1002623,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1002624,\"user_id\":null,\"contact_id\":6167,\"lead_id\":null},{\"id\":1002625,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:39] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {\"job_class\":\"Jiminny\\\\Jobs\\\\Crm\\\\MatchActivityCrmData\",\"attempts\":1,\"retry_after\":1,\"delay\":3} {\"correlation_id\":\"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613840,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613840} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613840,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613840,\"participants\":[{\"id\":1001764,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001765,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":244,\"contact_id\":4487,\"owner_id\":261} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":244,\"contact_id\":4487,\"opportunity_id\":299} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613840,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613840,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613840} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613840,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613840,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613833,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613833} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613833,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613833,\"participants\":[{\"id\":1001750,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001751,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":1.0,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613833,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613833,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613833} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613833,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613833,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613827,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613827} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613827,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613827,\"participants\":[{\"id\":1001734,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001735,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613827,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613827,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613827} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613827,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613827,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"d1d42ab0-5c87-42e8-a91f-a56b538619ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613826,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613826} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613826,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613826,\"participants\":[{\"id\":1001732,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001733,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613826,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613826,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613826} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613826,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613826,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"861e79c7-b5d3-4476-b429-0f1b4cf196a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613820,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613820} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613820,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613820,\"participants\":[{\"id\":1001721,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001722,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613820,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613820,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613820} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613820,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613820,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"97a99ff2-5956-4d77-837b-790c01b09967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613818,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613818} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613818,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613818,\"participants\":[{\"id\":1001717,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001718,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613818,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613818,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613818} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613818,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613818,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"300f80c3-6a45-4372-85a9-9fe439206596\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613812,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613812} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613812,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613812,\"participants\":[{\"id\":1001705,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001706,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613812,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613812,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613812} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613812,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613812,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"7a348156-9d36-4f25-ad5e-4fbfce8fd82a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613807,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4484,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613807} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613807,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613807,\"participants\":[{\"id\":1001690,\"user_id\":253,\"contact_id\":null,\"lead_id\":null},{\"id\":1001691,\"user_id\":null,\"contact_id\":4484,\"lead_id\":null}]} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613807,\"team_id\":2,\"email\":\"preslava.ivanova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":243,\"contact_id\":4484,\"owner_id\":253} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: ProspectCache - Fallback DB opportunity search {\"account_id\":243,\"contact_id\":4484} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":243,\"contact_id\":4484,\"opportunity_id\":276} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"tsvetomir.banovski@gmail.com\"} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613807,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613807} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613807,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613807,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4484,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"499c94c1-2716-49a2-9cdf-d5eb84f68ac6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613806,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34}} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613806} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613806,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613806,\"participants\":[{\"id\":1001688,\"user_id\":253,\"contact_id\":null,\"lead_id\":null},{\"id\":1001689,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null}]} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613806,\"team_id\":2,\"email\":\"preslava.ivanova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":244,\"contact_id\":4487,\"owner_id\":253} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: ProspectCache - Fallback DB opportunity search {\"account_id\":244,\"contact_id\":4487} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":244,\"contact_id\":4487,\"opportunity_id\":350} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613806,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613806} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613806,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613806,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34} {\"correlation_id\":\"7ce06f3c-60ee-46e5-a4dd-5b2b95b5bb64\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613805,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34}} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613805} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613805,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613805,\"participants\":[{\"id\":1001686,\"user_id\":253,\"contact_id\":null,\"lead_id\":null},{\"id\":1001687,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null}]} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613805,\"team_id\":2,\"email\":\"preslava.ivanova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613805,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613805} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613805,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613805,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34} {\"correlation_id\":\"9d268b15-7a74-40a7-a15c-f91054c54d96\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613698,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613698} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613698,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613698,\"participants\":[{\"id\":1001667,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001668,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613698,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613698,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613698} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613698,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613698,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"b347b4f8-2099-4fd0-86a2-735eb4d1c5a0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613697,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613697} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613697,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613697,\"participants\":[{\"id\":1001665,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001666,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613697,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613697,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613697} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613697,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613697,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"bbd8f44b-f8df-4187-889c-55f3536e4b2b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613696,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613696} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613696,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613696,\"participants\":[{\"id\":1001663,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001664,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613696,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613696,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613696} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613696,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613696,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"a49ef1a2-1961-4831-8425-89bedec362f9\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613695,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613695} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613695,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613695,\"participants\":[{\"id\":1001661,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001662,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613695,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613695,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613695} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613695,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613695,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"5a448789-544e-4bf0-906d-aa7745a76fa7\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613694,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613694} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613694,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613694,\"participants\":[{\"id\":1001659,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1001660,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613694,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613694,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613694} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613694,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613694,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"816a5557-12ef-4f10-964e-fb5da4d1024b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613157,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34}} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613157} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613157,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613157,\"participants\":[{\"id\":1000746,\"user_id\":253,\"contact_id\":null,\"lead_id\":null},{\"id\":1000747,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null}]} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613157,\"team_id\":2,\"email\":\"preslava.ivanova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613157,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613157} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613157,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613157,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34} {\"correlation_id\":\"03eaee80-dad2-4f52-b0c4-ca587c0bd5a1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613156,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34}} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613156} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613156,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613156,\"participants\":[{\"id\":1000744,\"user_id\":253,\"contact_id\":null,\"lead_id\":null},{\"id\":1000745,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null}]} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613156,\"team_id\":2,\"email\":\"preslava.ivanova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613156,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613156} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613156,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613156,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34} {\"correlation_id\":\"0e646a90-8a23-4b8f-bef7-d4404cdc448e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"859a4ec6-5c81-4283-bb96-c3ebaf5ff599\",\"trace_id\":\"f8a2783e-c54a-4d43-8cf6-61594479b0e7\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613155,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34}} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613155} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613155,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613155,\"participants\":[{\"id\":1000742,\"user_id\":253,\"contact_id\":null,\"lead_id\":null},{\"id\":1000743,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null}]} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"859a4ec6-5c81-4283-bb96-c3ebaf5ff599\",\"trace_id\":\"f8a2783e-c54a-4d43-8cf6-61594479b0e7\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613155,\"team_id\":2,\"email\":\"preslava.ivanova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613155,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613155} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613155,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613155,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34} {\"correlation_id\":\"e5deb2bc-6198-453a-bc77-dfc3b86ed330\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"859a4ec6-5c81-4283-bb96-c3ebaf5ff599\",\"trace_id\":\"f8a2783e-c54a-4d43-8cf6-61594479b0e7\"}\n[2026-05-11 11:17:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"859a4ec6-5c81-4283-bb96-c3ebaf5ff599\",\"trace_id\":\"f8a2783e-c54a-4d43-8cf6-61594479b0e7\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":613130,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613130} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613130,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":613130,\"participants\":[{\"id\":1000693,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1000694,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":613130,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":613130,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":613130} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":613130,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":613130,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"82d063fd-d6ec-4181-b9db-f7a3ef17fdaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612924,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":165,\"stage_id\":89}} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612924} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612924,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612924,\"participants\":[{\"id\":1000290,\"user_id\":19,\"contact_id\":null,\"lead_id\":null},{\"id\":1000291,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612924,\"team_id\":2,\"email\":\"james.graham@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":69,\"contact_id\":97,\"owner_id\":19} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":69,\"contact_id\":97,\"opportunity_id\":165} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612924,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612924} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612924,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612924,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":165,\"stage_id\":89} {\"correlation_id\":\"cb00d0fd-ad25-43c5-8390-7596ea614d43\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612923,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":165,\"stage_id\":89}} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612923} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612923,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612923,\"participants\":[{\"id\":1000288,\"user_id\":19,\"contact_id\":null,\"lead_id\":null},{\"id\":1000289,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612923,\"team_id\":2,\"email\":\"james.graham@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612923,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612923} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612923,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612923,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":165,\"stage_id\":89} {\"correlation_id\":\"2c16c154-a215-4582-9980-ebd7ee64044a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612922,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":165,\"stage_id\":89}} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612922} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612922,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612922,\"participants\":[{\"id\":1000286,\"user_id\":19,\"contact_id\":null,\"lead_id\":null},{\"id\":1000287,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612922,\"team_id\":2,\"email\":\"james.graham@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612922,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612922} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612922,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612922,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":165,\"stage_id\":89} {\"correlation_id\":\"4b1d2748-24b2-4a6b-8e7a-2fef29e92699\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612847,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612847} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612847,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612847,\"participants\":[{\"id\":1000130,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1000131,\"user_id\":261,\"contact_id\":null,\"lead_id\":null},{\"id\":1000151,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null}]} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:43] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"email\",\"identifier\":\"adelina.petrova@jiminny.com\"} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:44] local.INFO: [Hubspot] Failed to fetch contact {\"email\":\"adelina.petrova@jiminny.com\",\"reason\":\"[404] Client error: `GET https://api.hubapi.com/crm/v3/objects/contacts/adelina.petrova%40jiminny.com?properties=email%2Cfirstname%2Clastname%2Ccountry%2Cphone%2Cmobilephone%2Cjobtitle%2Chubspot_owner_id%2Cassociatedcompanyid%2Cphoto&archived=0&idProperty=email` resulted in a `404 Not Found` response\"} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:44] local.INFO: [Prospect match] API returned empty result, caching the miss with empty prospect data {\"identifier_type\":\"email\",\"identifier\":\"adelina.petrova@jiminny.com\"} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:44] local.WARNING: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":1,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e16c1-d (truncated...)\n\"} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:44] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {\"job_class\":\"Jiminny\\\\Jobs\\\\Crm\\\\MatchActivityCrmData\",\"attempts\":1,\"retry_after\":1,\"delay\":5} {\"correlation_id\":\"370e35c5-d81b-4c82-987e-e6bfe92913c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:44] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612822,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:44] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612822} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:44] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612822,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:44] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612822,\"participants\":[{\"id\":1000080,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1000081,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612822,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612822,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612822} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612822,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612822,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"629c3489-2741-42d3-872d-118c8ddef317\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612819,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612819} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612819,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612819,\"participants\":[{\"id\":1000073,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1000074,\"user_id\":261,\"contact_id\":null,\"lead_id\":null},{\"id\":1000075,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:45] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:46] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:46] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:46] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:46] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:46] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612819,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:46] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"adelina.petrova@jiminny.com\"} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:46] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"adelina.petrova@jiminny.com\"} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:47] local.WARNING: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":1,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e16c1-e (truncated...)\n\"} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:47] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {\"job_class\":\"Jiminny\\\\Jobs\\\\Crm\\\\MatchActivityCrmData\",\"attempts\":1,\"retry_after\":1,\"delay\":4} {\"correlation_id\":\"275577f1-42f7-466e-9ce6-c17b3f2fa4ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612673,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612673} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612673,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612673,\"participants\":[{\"id\":999993,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":999994,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612673,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612673,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612673} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:48] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612673,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:49] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612673,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"7d0f2fd2-918d-403e-a6ce-e803fbdc5b08\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:49] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612642,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:49] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612642} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:49] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612642,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:49] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612642,\"participants\":[{\"id\":999935,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":999936,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:49] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:49] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612642,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612642,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612642} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612642,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612642,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"97ce283e-ee51-4404-bc23-21d951bddd4b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612598,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612598} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612598,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612598,\"participants\":[{\"id\":999857,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999858,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":243,\"contact_id\":4491,\"owner_id\":206} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: ProspectCache - Fallback DB opportunity search {\"account_id\":243,\"contact_id\":4491} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":243,\"contact_id\":4491,\"opportunity_id\":276} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612598,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612598,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612598} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612598,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:51] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612598,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"dd9259e7-418a-47a0-8057-6d73eb23b66f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612597,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612597} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612597,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612597,\"participants\":[{\"id\":999855,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999856,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612597,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:53] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:54] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612597,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:54] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612597} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:54] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612597,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:54] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612597,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"e3420252-13cf-48c2-bb64-835fa0b7a4a4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612596,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612596} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612596,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612596,\"participants\":[{\"id\":999853,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999854,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612596,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612596,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612596} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612596,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:55] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612596,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"0a7ad0b2-4fbb-4bc6-ac63-ab9a3755668d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612595,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612595} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612595,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612595,\"participants\":[{\"id\":999851,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999852,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612595,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612595,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612595} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612595,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:56] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612595,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"ab7b332f-3248-47be-ae07-2194ad2db67f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612594,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612594} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612594,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612594,\"participants\":[{\"id\":999849,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999850,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612594,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612594,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612594} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612594,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:57] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612594,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"3e75582e-1c8d-4a79-b2f5-c5b402351b6e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612593,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612593} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612593,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612593,\"participants\":[{\"id\":999847,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999848,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612593,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612593,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612593} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612593,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612593,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"aa3bcf96-a28f-41da-9705-9ed54e0c2102\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612592,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612592} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612592,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:58] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612592,\"participants\":[{\"id\":999845,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999846,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612592,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612592,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612592} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612592,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612592,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"26135f3d-da44-4d76-a60f-10382d2fb967\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612591,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612591} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612591,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:17:59] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612591,\"participants\":[{\"id\":999843,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999844,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612591,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612591,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612591} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612591,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612591,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"b8d871e8-9441-4887-b52c-673ba317b86f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612590,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612590} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612590,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612590,\"participants\":[{\"id\":999841,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999842,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612590,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612590,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612590} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612590,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:00] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612590,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"a5db6a27-7474-478f-ae10-588189dcf4c5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612589,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612589} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612589,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612589,\"participants\":[{\"id\":999839,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999840,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612589,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612589,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612589} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612589,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612589,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"cf2e7822-f4b9-4a8d-8a4f-191d404ca5d8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612588,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612588} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612588,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:01] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612588,\"participants\":[{\"id\":999837,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999838,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612588,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612588,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612588} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612588,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612588,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"48ab04f3-8832-412a-b14d-ef2d05d438c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":16.99,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:18:02] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612587,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612587} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612587,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612587,\"participants\":[{\"id\":999835,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999836,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612587,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612587,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612587} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612587,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612587,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"ddc565df-f051-4082-9bd2-4eb892b2bed2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612586,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612586} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612586,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612586,\"participants\":[{\"id\":999833,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999834,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612586,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612586,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612586} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612586,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:02] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612586,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"0ec5d5d4-7b90-4702-86a4-3dd3318a0456\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:03] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612585,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:03] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612585} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:03] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612585,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:03] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612585,\"participants\":[{\"id\":999831,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999832,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:03] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:03] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612585,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612585,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612585} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612585,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612585,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"06ce1669-8714-4bd5-b110-0d8905e544eb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612584,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:04] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612584} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:05] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612584,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:05] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612584,\"participants\":[{\"id\":999829,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999830,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:05] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:05] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:05] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:05] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612584,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612584,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612584} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612584,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612584,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"9e046bb0-fe09-4981-90d8-9e4e1a2d9821\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612583,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612583} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612583,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:06] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612583,\"participants\":[{\"id\":999827,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999828,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:07] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:07] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:07] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:07] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:07] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:07] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612583,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:07] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612583,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:07] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612583} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:07] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612583,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:08] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612583,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"4bb39316-5956-491d-9643-e85e3a2d2295\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612582,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612582} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612582,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612582,\"participants\":[{\"id\":999825,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999826,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612582,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612582,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612582} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:09] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612582,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:10] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612582,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"233ce7c6-8ba8-4646-b04e-55dc11e56023\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:11] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612581,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:11] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612581} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:11] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612581,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:11] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612581,\"participants\":[{\"id\":999823,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999824,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:11] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":4.14,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:18:11] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:11] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:11] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:11] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:11] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:12] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612581,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:12] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612581,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:12] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612581} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:12] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612581,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:12] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612581,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"225d184a-6550-4e96-b55f-b2f6affc3f72\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612565,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612565} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612565,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612565,\"participants\":[{\"id\":999789,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999790,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null}]} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"feff8215-75fe-40b2-916e-951435e048aa\",\"trace_id\":\"46d069ed-7c2b-4fdc-9679-9ec571a88271\"}\n[2026-05-11 11:18:15] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612565,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612565,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612565} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:15] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612565,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:16] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612565,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"b86ac27b-8e79-4924-8480-832bda0a162c\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:16] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"feff8215-75fe-40b2-916e-951435e048aa\",\"trace_id\":\"46d069ed-7c2b-4fdc-9679-9ec571a88271\"}\n[2026-05-11 11:18:16] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612563,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34}} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:16] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612563} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:16] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612563,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:16] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612563,\"participants\":[{\"id\":999784,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999785,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null}]} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:17] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:17] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:17] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612563,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:17] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":244,\"contact_id\":4487,\"owner_id\":206} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:17] local.INFO: ProspectCache - Fallback DB opportunity search {\"account_id\":244,\"contact_id\":4487} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:17] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":244,\"contact_id\":4487,\"opportunity_id\":350} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:17] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"feff8215-75fe-40b2-916e-951435e048aa\",\"trace_id\":\"46d069ed-7c2b-4fdc-9679-9ec571a88271\"}\n[2026-05-11 11:18:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"feff8215-75fe-40b2-916e-951435e048aa\",\"trace_id\":\"46d069ed-7c2b-4fdc-9679-9ec571a88271\"}\n[2026-05-11 11:18:18] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:19] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612563,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:19] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612563} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:19] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612563,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:19] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612563,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34} {\"correlation_id\":\"8e17d06e-8ffc-4d65-80f6-6b11aa27d46e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:19] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":3.06,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:18:19] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"5a640073-717d-40da-ad67-be02e37c56a2\",\"trace_id\":\"46d069ed-7c2b-4fdc-9679-9ec571a88271\"}\n[2026-05-11 11:18:20] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612562,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:20] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612562} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:20] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612562,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:20] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612562,\"participants\":[{\"id\":999782,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":999783,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:20] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:20] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:20] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:20] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:20] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"email\",\"identifier\":\"447782589921@txt.staging.jiminny.com\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:21] local.INFO: [Hubspot] Failed to fetch contact {\"email\":\"447782589921@txt.staging.jiminny.com\",\"reason\":\"[404] Client error: `GET https://api.hubapi.com/crm/v3/objects/contacts/447782589921%40txt.staging.jiminny.com?properties=email%2Cfirstname%2Clastname%2Ccountry%2Cphone%2Cmobilephone%2Cjobtitle%2Chubspot_owner_id%2Cassociatedcompanyid%2Cphoto&archived=0&idProperty=email` resulted in a `404 Not Found` response\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:21] local.INFO: [Prospect match] API returned empty result, caching the miss with empty prospect data {\"identifier_type\":\"email\",\"identifier\":\"447782589921@txt.staging.jiminny.com\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:21] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.24,\"average_seconds_per_request\":0.24} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:22] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"447782589921@txt.staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:22] local.INFO: [Prospect match] Cache miss {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\",\"crm\":\"hubspot\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:22] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:22] local.INFO: [HubSpot] importAccount {\"crm_provider_id\":\"749766179\",\"config_id\":2} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:22] local.INFO: [HubSpot] CRM Search requested {\"request\":{\"filterGroups\":[{\"filters\":[{\"propertyName\":\"associations.company\",\"operator\":\"EQ\",\"value\":\"749766179\"},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedwon\",\"4040964\",\"59247967\"]},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedlost\",\"4040965\",\"59247968\"]}]}],\"sorts\":[{\"propertyName\":\"modifieddate\",\"direction\":\"DESCENDING\"}],\"properties\":[\"dealname\",\"amount\",\"hubspot_owner_id\",\"pipeline\",\"dealstage\",\"closedate\",\"deal_currency_code\"],\"limit\":200}} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:22] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":10,\"total_elapsed_seconds\":0.32,\"average_seconds_per_request\":0.32} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612562,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612562,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612562} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612562,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612562,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"dd25d3ff-8533-4fac-bf1d-a0656234ea85\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612561,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612561} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612561,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612561,\"participants\":[{\"id\":999780,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999781,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:23] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612561,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"email\",\"identifier\":\"447700174614.447782589921.OeREojLVnk@txt.staging.jiminny.com\"} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [Hubspot] Failed to fetch contact {\"email\":\"447700174614.447782589921.OeREojLVnk@txt.staging.jiminny.com\",\"reason\":\"[404] Client error: `GET https://api.hubapi.com/crm/v3/objects/contacts/447700174614.447782589921.OeREojLVnk%40txt.staging.jiminny.com?properties=email%2Cfirstname%2Clastname%2Ccountry%2Cphone%2Cmobilephone%2Cjobtitle%2Chubspot_owner_id%2Cassociatedcompanyid%2Cphoto&archived=0&idProperty=email` resulted in a `404 Not Found` response\"} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [Prospect match] API returned empty result, caching the miss with empty prospect data {\"identifier_type\":\"email\",\"identifier\":\"447700174614.447782589921.OeREojLVnk@txt.staging.jiminny.com\"} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"447700174614.447782589921.OeREojLVnk@txt.staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612561,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612561} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612561,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612561,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"726b3674-684a-493a-8b19-6872339717d0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612560,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612560} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612560,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612560,\"participants\":[{\"id\":999778,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":999779,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"447782589921@txt.staging.jiminny.com\"} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"447782589921@txt.staging.jiminny.com\"} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"447782589921@txt.staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612560,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612560,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612560} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612560,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:24] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612560,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"028beef2-7b15-4dd5-80e0-0629fd918aaf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612559,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":1.89,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:18:26] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612559} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612559,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612559,\"participants\":[{\"id\":999776,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999777,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612559,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":69,\"contact_id\":97,\"owner_id\":206} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: ProspectCache - Fallback DB opportunity search {\"account_id\":69,\"contact_id\":97} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":69,\"contact_id\":97,\"opportunity_id\":5011} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612559,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612559} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612559,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:26] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612559,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"4e01dc54-b912-46cc-bf4c-c6a0fd5627f0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612558,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612558} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612558,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612558,\"participants\":[{\"id\":999774,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999775,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612558,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612558,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612558} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612558,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612558,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"49d539c3-0bf6-4b41-a98a-fbca0ca960cd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612557,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612557} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612557,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612557,\"participants\":[{\"id\":999772,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999773,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612557,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612557,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612557} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612557,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612557,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"d6767fbf-b735-4480-843b-1d9d574b133d\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612556,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612556} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612556,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612556,\"participants\":[{\"id\":999770,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999771,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612556,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612556,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612556} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612556,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:27] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612556,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"04fa4b73-a2e0-4804-8722-18bdec56afab\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612555,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612555} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612555,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612555,\"participants\":[{\"id\":999768,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999769,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612555,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612555,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612555} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612555,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612555,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"1b1e56f6-7c50-4a00-988b-fcfda312d1c8\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612554,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612554} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612554,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612554,\"participants\":[{\"id\":999766,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999767,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612554,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612554,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612554} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612554,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612554,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"9ab5fb67-2687-4495-84e5-d9492e1ad9ae\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612553,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612553} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612553,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:28] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612553,\"participants\":[{\"id\":999764,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999765,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612553,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612553,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612553} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612553,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:29] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612553,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"95dabb64-e2cf-4104-9858-8b381c71b4d6\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612552,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612552} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612552,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612552,\"participants\":[{\"id\":999762,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999763,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612552,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612552,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612552} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612552,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612552,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"cdcd7a84-bff0-4af9-b585-aa58265b4692\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612551,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612551} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612551,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612551,\"participants\":[{\"id\":999760,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999761,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612551,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612551,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612551} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612551,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612551,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"3e0c6785-d4f6-48e6-a6b2-8289e6764698\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612550,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612550} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612550,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612550,\"participants\":[{\"id\":999758,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999759,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612550,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612550,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612550} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612550,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612550,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"e1db7837-d58d-4bd7-b7e5-f6263da1cf69\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612549,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34}} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612549} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612549,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612549,\"participants\":[{\"id\":999756,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999757,\"user_id\":null,\"contact_id\":97,\"lead_id\":null}]} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612549,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinsoncrusoe@test.com\"} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612549,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612549} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612549,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612549,\"remote_search\":true,\"lead_id\":null,\"contact_id\":97,\"account_id\":69,\"opportunity_id\":5011,\"stage_id\":34} {\"correlation_id\":\"bc7e6057-3b4a-446f-8989-b0c166f4bec0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612365,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612365} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612365,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612365,\"participants\":[{\"id\":999563,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999564,\"user_id\":206,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":243,\"contact_id\":4491,\"owner_id\":206} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: ProspectCache - Fallback DB opportunity search {\"account_id\":243,\"contact_id\":4491} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:30] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":243,\"contact_id\":4491,\"opportunity_id\":276} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612365,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612365,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612365} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612365,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612365,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"8e7dd343-a500-4f4c-9e6d-55a13cdb2112\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612360,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612360} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612360,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612360,\"participants\":[{\"id\":999552,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999553,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999565,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612360,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.29,\"average_seconds_per_request\":0.29} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612360,\"participants_processed\":3,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612360} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612360,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612360,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"21abffc3-5241-4708-b3e0-abd2dd288cde\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612340,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612340} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612340,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612340,\"participants\":[{\"id\":999516,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999517,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999518,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":999519,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:31] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612340,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.34,\"average_seconds_per_request\":0.34} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612340,\"participants_processed\":4,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612340} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612340,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612340,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"1b3ea0b3-7411-4358-9981-f09a275a33dd\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":0.75,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:18:32] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612339,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612339} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612339,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612339,\"participants\":[{\"id\":999514,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999515,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999540,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612339,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612339,\"participants_processed\":3,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612339} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612339,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612339,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"9361adaf-f558-47e1-8c17-29624076d6b0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612336,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36}} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612336} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612336,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612336,\"participants\":[{\"id\":999508,\"user_id\":null,\"contact_id\":4491,\"lead_id\":null},{\"id\":999509,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":999512,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":999513,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"horencho@gmail.com\"} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612336,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612336,\"participants_processed\":4,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612336} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612336,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612336,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4491,\"account_id\":243,\"opportunity_id\":276,\"stage_id\":36} {\"correlation_id\":\"df588253-5bf4-461b-848b-24cdc4f6b9ce\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612183,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612183} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612183,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612183,\"participants\":[{\"id\":999227,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":999228,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":244,\"contact_id\":4487,\"owner_id\":261} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":244,\"contact_id\":4487,\"opportunity_id\":299} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612183,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612183,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612183} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:32] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612183,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612183,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"1a3a820f-a56a-4ab6-a0b0-1a27257889a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612182,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612182} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612182,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612182,\"participants\":[{\"id\":999225,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":999226,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612182,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612182,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612182} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612182,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612182,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"0ddb68fc-c275-46bd-98a1-95de8b8b0f8e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612181,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612181} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612181,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612181,\"participants\":[{\"id\":999223,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":999224,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612181,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612181,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612181} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612181,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612181,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"1a86dfbb-2141-4f4a-940b-43fbd1f8ddf1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612180,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612180} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612180,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612180,\"participants\":[{\"id\":999221,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":999222,\"user_id\":261,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612180,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612180,\"participants_processed\":2,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612180} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612180,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:33] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612180,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"correlation_id\":\"4f63b5e4-5027-4921-92f6-5421affdb43f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":611455,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":611455} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":611455,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":611455,\"participants\":[{\"id\":997961,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997962,\"user_id\":1460,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [Hubspot] Failed to fetch contact {\"email\":\"support@staging.jiminny.com\",\"reason\":\"[404] Client error: `GET https://api.hubapi.com/crm/v3/objects/contacts/support%40staging.jiminny.com?properties=email%2Cfirstname%2Clastname%2Ccountry%2Cphone%2Cmobilephone%2Cjobtitle%2Chubspot_owner_id%2Cassociatedcompanyid%2Cphoto&archived=0&idProperty=email` resulted in a `404 Not Found` response\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [Prospect match] API returned empty result, caching the miss with empty prospect data {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.23,\"average_seconds_per_request\":0.23} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [Prospect match] Cache miss {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\",\"crm\":\"hubspot\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:34] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:35] local.INFO: [HubSpot] importAccount {\"crm_provider_id\":\"749766179\",\"config_id\":2} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:35] local.INFO: [HubSpot] CRM Search requested {\"request\":{\"filterGroups\":[{\"filters\":[{\"propertyName\":\"associations.company\",\"operator\":\"EQ\",\"value\":\"749766179\"},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedwon\",\"4040964\",\"59247967\"]},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedlost\",\"4040965\",\"59247968\"]}]}],\"sorts\":[{\"propertyName\":\"modifieddate\",\"direction\":\"DESCENDING\"}],\"properties\":[\"dealname\",\"amount\",\"hubspot_owner_id\",\"pipeline\",\"dealstage\",\"closedate\",\"deal_currency_code\"],\"limit\":200}} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:35] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":10,\"total_elapsed_seconds\":0.27,\"average_seconds_per_request\":0.27} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":611455,\"team_id\":2,\"email\":\"aneliya.angelova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":611455,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":611455} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":611455,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":611455,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"05046735-5c60-4f00-bdf3-b8c4869f818e\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":611451,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":611451} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":611451,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":611451,\"participants\":[{\"id\":997955,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997956,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [Hubspot] Failed to fetch contact {\"email\":\"support@staging.jiminny.com\",\"reason\":\"[404] Client error: `GET https://api.hubapi.com/crm/v3/objects/contacts/support%40staging.jiminny.com?properties=email%2Cfirstname%2Clastname%2Ccountry%2Cphone%2Cmobilephone%2Cjobtitle%2Chubspot_owner_id%2Cassociatedcompanyid%2Cphoto&archived=0&idProperty=email` resulted in a `404 Not Found` response\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:36] local.INFO: [Prospect match] API returned empty result, caching the miss with empty prospect data {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:37] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.25,\"average_seconds_per_request\":0.25} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:37] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:37] local.INFO: [Prospect match] Cache miss {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\",\"crm\":\"hubspot\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:37] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:37] local.INFO: [HubSpot] importAccount {\"crm_provider_id\":\"749766179\",\"config_id\":2} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:37] local.INFO: [HubSpot] CRM Search requested {\"request\":{\"filterGroups\":[{\"filters\":[{\"propertyName\":\"associations.company\",\"operator\":\"EQ\",\"value\":\"749766179\"},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedwon\",\"4040964\",\"59247967\"]},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedlost\",\"4040965\",\"59247968\"]}]}],\"sorts\":[{\"propertyName\":\"modifieddate\",\"direction\":\"DESCENDING\"}],\"properties\":[\"dealname\",\"amount\",\"hubspot_owner_id\",\"pipeline\",\"dealstage\",\"closedate\",\"deal_currency_code\"],\"limit\":200}} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:38] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":10,\"total_elapsed_seconds\":0.44,\"average_seconds_per_request\":0.44} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":611451,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":3.16,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:18:40] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":611451,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":611451} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":611451,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":611451,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"471d15bb-ac2d-44a9-ad19-7e4dcffe21a5\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":611087,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":611087} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":611087,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":611087,\"participants\":[{\"id\":997368,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997369,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":611087,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":611087,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":611087} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":611087,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":611087,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"57ae5f63-477d-4d91-a9a3-8706092bf1e1\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":611076,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":611076} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":611076,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":611076,\"participants\":[{\"id\":997346,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997347,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":611076,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":611076,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":611076} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":611076,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":611076,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"2f7ba226-575b-41a7-a3d7-85c8b1fbe96b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610935,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610935} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610935,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610935,\"participants\":[{\"id\":997141,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997142,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610935,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610935,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610935} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610935,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610935,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"f2e5be67-dc9b-4211-994b-4582b631e128\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610915,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610915} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610915,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610915,\"participants\":[{\"id\":997104,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997105,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610915,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610915,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610915} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610915,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610915,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"b9f7b83f-19d2-4fc2-812d-a9d4dbaa6169\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610900,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610900} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610900,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610900,\"participants\":[{\"id\":997081,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997082,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610900,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610900,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610900} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610900,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:42] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610900,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"c45e3abe-1c98-4191-89dc-06c37af6a89a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610885,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610885} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610885,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610885,\"participants\":[{\"id\":997051,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997052,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610885,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610885,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610885} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610885,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610885,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"71c5715e-33f9-4ac4-a037-3f8d92f9323f\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610878,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610878} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610878,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610878,\"participants\":[{\"id\":997035,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997036,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610878,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610878,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610878} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610878,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:43] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610878,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"981ea94d-43c4-4549-a61a-38c0e6168aa4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610874,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610874} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610874,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610874,\"participants\":[{\"id\":997025,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997026,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610874,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610874,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610874} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610874,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610874,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"85e22bcd-46df-43fd-af31-f1fd6ea93304\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610867,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610867} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610867,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610867,\"participants\":[{\"id\":997011,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":997012,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610867,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610867,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610867} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:44] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610867,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610867,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"20f53637-e428-4d97-9c00-77128a6693bf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610764,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610764} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610764,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610764,\"participants\":[{\"id\":996951,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996952,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610764,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610764,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610764} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610764,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610764,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"31fb51e4-214a-4331-9ccb-e88251c31d23\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610617,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610617} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610617,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610617,\"participants\":[{\"id\":996641,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996642,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610617,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610617,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610617} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610617,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610617,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"1195ea0b-ff6f-4868-85b8-00e5910a6ebb\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610539,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610539} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610539,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610539,\"participants\":[{\"id\":996485,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996486,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610539,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610539,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610539} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610539,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610539,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"a12553b5-487b-4fe5-9f92-b4f1ea60e934\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:45] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":0.4,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610528,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610528} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610528,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610528,\"participants\":[{\"id\":996463,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996464,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610528,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610528,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610528} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610528,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610528,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"2cbcee52-8293-4463-b697-38db65d9f9c0\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610506,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610506} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610506,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610506,\"participants\":[{\"id\":996419,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996420,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610506,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610506,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610506} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610506,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610506,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"ef47bda9-11c9-43e9-9486-e279b2651ddf\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610497,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610497} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610497,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610497,\"participants\":[{\"id\":996401,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996402,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610497,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610497,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610497} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610497,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610497,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"5c552582-cc35-429e-a270-3c590292f4d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610490,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610490} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610490,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610490,\"participants\":[{\"id\":996385,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996386,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:46] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610490,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610490,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610490} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610490,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610490,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"1d9665e5-1818-48ff-9e74-77325bc59987\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610470,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610470} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610470,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610470,\"participants\":[{\"id\":996369,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996370,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610470,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610470,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610470} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610470,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610470,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"d7791858-9c04-4d8c-9509-dd01f1eae66b\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610462,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610462} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610462,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610462,\"participants\":[{\"id\":996353,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996354,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610462,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610462,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610462} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610462,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610462,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"7eda1fd5-8bda-4f9e-94d0-866e72813503\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610451,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610451} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610451,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610451,\"participants\":[{\"id\":996340,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996341,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610451,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610451,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610451} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610451,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610451,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"13f3d6e6-73ba-4280-ae4d-1687fc9104d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610438,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610438} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610438,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610438,\"participants\":[{\"id\":996320,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996321,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610438,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610438,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610438} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610438,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610438,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"107b5e13-81e1-4cb5-b64e-174334224d3a\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610426,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610426} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610426,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:47] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610426,\"participants\":[{\"id\":996306,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996307,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610426,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610426,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610426} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610426,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610426,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"f048c662-0e8e-4156-905b-0e237663e017\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610403,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610403} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610403,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610403,\"participants\":[{\"id\":996282,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":996283,\"user_id\":18,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"support@staging.jiminny.com\"} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"support@staging.jiminny.com\",\"domain\":\"jiminny.com\"} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610403,\"team_id\":2,\"email\":\"veselin.kulov@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610403,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610403} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610403,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610403,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"correlation_id\":\"0bf21e74-7810-4594-8fa0-ac9df6a5b1c4\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":610400,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34}} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610400} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610400,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":610400,\"participants\":[{\"id\":996275,\"user_id\":1460,\"contact_id\":null,\"lead_id\":null},{\"id\":996276,\"user_id\":206,\"contact_id\":null,\"lead_id\":null},{\"id\":996277,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null}]} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610400,\"team_id\":2,\"email\":\"aneliya.angelova@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":610400,\"team_id\":2,\"email\":\"horen.kirazyan@jiminny.onmicrosoft.com\"} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: ProspectCache - Searching DB for opportunity by owner {\"account_id\":244,\"contact_id\":4487,\"owner_id\":1460} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: ProspectCache - Fallback DB opportunity search {\"account_id\":244,\"contact_id\":4487} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: ProspectCache - Opportunity DB search results {\"account_id\":244,\"contact_id\":4487,\"opportunity_id\":350} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":610400,\"participants_processed\":3,\"exact_matches\":1,\"domain_matches\":0,\"best_match_found\":true} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":610400} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":610400,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":610400,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":350,\"stage_id\":34} {\"correlation_id\":\"ddac2edc-3725-4efd-b520-337c200e17d2\",\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\"}\n[2026-05-11 11:18:48] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":614382,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614382} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614382,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":614382,\"participants\":[{\"id\":1002632,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1002633,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [Hubspot] Failed to fetch contact {\"email\":\"nikolay.nikolov@jiminny.com\",\"reason\":\"[404] Client error: `GET https://api.hubapi.com/crm/v3/objects/contacts/nikolay.nikolov%40jiminny.com?properties=email%2Cfirstname%2Clastname%2Ccountry%2Cphone%2Cmobilephone%2Cjobtitle%2Chubspot_owner_id%2Cassociatedcompanyid%2Cphoto&archived=0&idProperty=email` resulted in a `404 Not Found` response\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:48] local.INFO: [Prospect match] API returned empty result, caching the miss with empty prospect data {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:49] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.51,\"average_seconds_per_request\":0.51} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:49] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"nikolay.nikolov@jiminny.com\",\"domain\":\"jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:49] local.INFO: [Prospect match] Cache miss {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\",\"crm\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:49] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:49] local.INFO: [HubSpot] importAccount {\"crm_provider_id\":\"749766179\",\"config_id\":2} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:49] local.INFO: [HubSpot] CRM Search requested {\"request\":{\"filterGroups\":[{\"filters\":[{\"propertyName\":\"associations.company\",\"operator\":\"EQ\",\"value\":\"749766179\"},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedwon\",\"4040964\",\"59247967\"]},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedlost\",\"4040965\",\"59247968\"]}]}],\"sorts\":[{\"propertyName\":\"modifieddate\",\"direction\":\"DESCENDING\"}],\"properties\":[\"dealname\",\"amount\",\"hubspot_owner_id\",\"pipeline\",\"dealstage\",\"closedate\",\"deal_currency_code\"],\"limit\":200}} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:49] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":10,\"total_elapsed_seconds\":0.35,\"average_seconds_per_request\":0.35} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:50] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":614382,\"team_id\":2,\"email\":\"nikolay.nikolov@jiminny.onmicrosoft.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:50] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":614382,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614382} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614382,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":614382,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"adc1eae9-d4cb-481e-922f-179bac5a8934\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":614381,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614381} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614381,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":614381,\"participants\":[{\"id\":1002630,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1002631,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"nikolay.nikolov@jiminny.com\",\"domain\":\"jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":614381,\"team_id\":2,\"email\":\"nikolay.nikolov@jiminny.onmicrosoft.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":614381,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614381} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614381,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":614381,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"7fad664c-6cfc-402b-adac-89a4c8c5f4d1\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":615092,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":615092} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":615092,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":615092,\"participants\":[{\"id\":1004102,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1004103,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"nikolay.nikolov@jiminny.com\",\"domain\":\"jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":615092,\"team_id\":2,\"email\":\"nikolay.nikolov@jiminny.onmicrosoft.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":615092,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":615092} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":615092,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":615092,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8e4b7ef5-6a2b-4f08-8a0d-528e39fe7930\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":614436,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89}} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614436} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614436,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":614436,\"participants\":[{\"id\":1002751,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1002752,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"nikolay.nikolov@jiminny.com\",\"domain\":\"jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":614436,\"team_id\":2,\"email\":\"nikolay.nikolov@jiminny.onmicrosoft.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":614436,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614436} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614436,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":614436,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":26,\"opportunity_id\":22,\"stage_id\":89} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"8df9c375-43bc-41b1-a457-36d722a98ea1\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":614378,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":6167,\"account_id\":null,\"opportunity_id\":null,\"stage_id\":null}} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:50] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614378} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:50] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614378,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:50] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":614378,\"participants\":[{\"id\":1002623,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1002624,\"user_id\":null,\"contact_id\":6167,\"lead_id\":null},{\"id\":1002625,\"user_id\":89,\"contact_id\":null,\"lead_id\":null}]} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"nikolay.nikolov@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"nikolay.nikolov@jiminny.com\",\"domain\":\"jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"nmalchev@gmail.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":614378,\"team_id\":2,\"email\":\"nikolay.nikolov@jiminny.onmicrosoft.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":614378,\"participants_processed\":3,\"exact_matches\":1,\"domain_matches\":1,\"best_match_found\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":614378} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":614378,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":614378,\"remote_search\":true,\"lead_id\":null,\"contact_id\":6167,\"account_id\":null,\"opportunity_id\":null,\"stage_id\":null} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"d586f923-bac1-482b-a699-2c7c262dee65\"}\n[2026-05-11 11:18:51] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612847,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612847} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612847,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612847,\"participants\":[{\"id\":1000130,\"user_id\":null,\"contact_id\":null,\"lead_id\":null},{\"id\":1000131,\"user_id\":261,\"contact_id\":null,\"lead_id\":null},{\"id\":1000151,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null}]} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"email\",\"identifier\":\"adelina.petrova@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":0.84,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:18:51] local.INFO: [Hubspot] Failed to fetch contact {\"email\":\"adelina.petrova@jiminny.com\",\"reason\":\"[404] Client error: `GET https://api.hubapi.com/crm/v3/objects/contacts/adelina.petrova%40jiminny.com?properties=email%2Cfirstname%2Clastname%2Ccountry%2Cphone%2Cmobilephone%2Cjobtitle%2Chubspot_owner_id%2Cassociatedcompanyid%2Cphoto&archived=0&idProperty=email` resulted in a `404 Not Found` response\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:51] local.INFO: [Prospect match] API returned empty result, caching the miss with empty prospect data {\"identifier_type\":\"email\",\"identifier\":\"adelina.petrova@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:52] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.28,\"average_seconds_per_request\":0.28} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:52] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"adelina.petrova@jiminny.com\",\"domain\":\"jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:52] local.INFO: [Prospect match] Cache miss {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\",\"crm\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:52] local.INFO: [Prospect match] Cache miss, calling the API {\"identifier_type\":\"domain\",\"identifier\":\"jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:52] local.INFO: [HubSpot] importAccount {\"crm_provider_id\":\"749766179\",\"config_id\":2} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:52] local.INFO: [HubSpot] CRM Search requested {\"request\":{\"filterGroups\":[{\"filters\":[{\"propertyName\":\"associations.company\",\"operator\":\"EQ\",\"value\":\"749766179\"},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedwon\",\"4040964\",\"59247967\"]},{\"propertyName\":\"dealstage\",\"operator\":\"NOT_IN\",\"values\":[\"closedlost\",\"4040965\",\"59247968\"]}]}],\"sorts\":[{\"propertyName\":\"modifieddate\",\"direction\":\"DESCENDING\"}],\"properties\":[\"dealname\",\"amount\",\"hubspot_owner_id\",\"pipeline\",\"dealstage\",\"closedate\",\"deal_currency_code\"],\"limit\":200}} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:53] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":10,\"total_elapsed_seconds\":0.43,\"average_seconds_per_request\":0.43} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:53] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612847,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:53] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:53] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612847,\"participants_processed\":3,\"exact_matches\":1,\"domain_matches\":1,\"best_match_found\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:54] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612847} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:54] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612847,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:54] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612847,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"2dfb95b0-e84e-4956-8d2c-59d97cc1a442\"}\n[2026-05-11 11:18:54] local.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":612819,\"remote_search\":true,\"set_configuration\":2,\"old_state\":{\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36}} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612819} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612819,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [MatchActivityCrmData] Participants old state {\"activity\":612819,\"participants\":[{\"id\":1000073,\"user_id\":null,\"contact_id\":4487,\"lead_id\":null},{\"id\":1000074,\"user_id\":261,\"contact_id\":null,\"lead_id\":null},{\"id\":1000075,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"robinson@crusoe.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":612819,\"team_id\":2,\"email\":\"adelina.petrova@jiminny.onmicrosoft.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [Prospect match] Cache / local search hit {\"identifier_type\":\"email\",\"identifier\":\"adelina.petrova@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {\"identifier_type\":\"email\",\"identifier\":\"adelina.petrova@jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [Prospect match] Resolved company domain from email {\"email\":\"adelina.petrova@jiminny.com\",\"domain\":\"jiminny.com\"} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":612819,\"participants_processed\":3,\"exact_matches\":1,\"domain_matches\":1,\"best_match_found\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":612819} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":612819,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:54] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":612819,\"remote_search\":true,\"lead_id\":null,\"contact_id\":4487,\"account_id\":244,\"opportunity_id\":299,\"stage_id\":36} {\"trace_id\":\"6cee2988-85fe-44ce-ba47-56fc0392669c\",\"correlation_id\":\"da5b27d2-94da-4c45-a312-1c293b8ad38d\"}\n[2026-05-11 11:18:57] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {\"worker\":\"\",\"peak_memory\":\"99.73 MB\",\"elapsed_seconds\":0.25,\"update_target\":\"activities\",\"should_iterate_again\":false} {\"correlation_id\":\"8c24420c-db53-4450-9cd8-db5d2426bd57\",\"trace_id\":\"5406d133-f6cd-4f5a-b463-9146e1dfb021\"}\n[2026-05-11 11:19:07] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"70d16739-7654-4185-99cb-49559aafc660\",\"trace_id\":\"d100f21a-5975-471a-b245-90b25b177c8f\"}\n[2026-05-11 11:19:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"70d16739-7654-4185-99cb-49559aafc660\",\"trace_id\":\"d100f21a-5975-471a-b245-90b25b177c8f\"}\n[2026-05-11 11:19:07] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"70d16739-7654-4185-99cb-49559aafc660\",\"trace_id\":\"d100f21a-5975-471a-b245-90b25b177c8f\"}\n[2026-05-11 11:19:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"91df8068-6c15-4614-947e-90f48574662c\",\"trace_id\":\"a9a86198-7521-4c0c-a89e-d23b34f2f8bf\"}\n[2026-05-11 11:19:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"91df8068-6c15-4614-947e-90f48574662c\",\"trace_id\":\"a9a86198-7521-4c0c-a89e-d23b34f2f8bf\"}\n[2026-05-11 11:19:15] local.NOTICE: Monitoring start {\"correlation_id\":\"6fae005c-3fcd-4718-86b0-f08f140f889c\",\"trace_id\":\"233ad400-a3ad-4093-8660-9e477cd6ca8f\"}\n[2026-05-11 11:19:15] local.NOTICE: Monitoring end {\"correlation_id\":\"6fae005c-3fcd-4718-86b0-f08f140f889c\",\"trace_id\":\"233ad400-a3ad-4093-8660-9e477cd6ca8f\"}\n[2026-05-11 11:19:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08b79017-e665-425f-8048-21f93b1abf3b\",\"trace_id\":\"bb7a7ea5-30d3-4a13-9c3c-84bc1f9c26e7\"}\n[2026-05-11 11:19:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08b79017-e665-425f-8048-21f93b1abf3b\",\"trace_id\":\"bb7a7ea5-30d3-4a13-9c3c-84bc1f9c26e7\"}\n[2026-05-11 11:19:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"0c31163b-b05f-4d3f-9a66-a2ce01d94010\",\"trace_id\":\"3dfb6352-28a3-4c77-b6ff-a11e0a7821a0\"}\n[2026-05-11 11:19:21] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"0c31163b-b05f-4d3f-9a66-a2ce01d94010\",\"trace_id\":\"3dfb6352-28a3-4c77-b6ff-a11e0a7821a0\"}\n[2026-05-11 11:19:22] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"0c31163b-b05f-4d3f-9a66-a2ce01d94010\",\"trace_id\":\"3dfb6352-28a3-4c77-b6ff-a11e0a7821a0\"}\n[2026-05-11 11:19:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"0c31163b-b05f-4d3f-9a66-a2ce01d94010\",\"trace_id\":\"3dfb6352-28a3-4c77-b6ff-a11e0a7821a0\"}\n[2026-05-11 11:20:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cb3a4a64-b00b-4f94-9e00-c190cd7a7a42\",\"trace_id\":\"acd43b75-f255-471f-9563-f03de03c7e23\"}\n[2026-05-11 11:20:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"cb3a4a64-b00b-4f94-9e00-c190cd7a7a42\",\"trace_id\":\"acd43b75-f255-471f-9563-f03de03c7e23\"}\n[2026-05-11 11:20:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cb3a4a64-b00b-4f94-9e00-c190cd7a7a42\",\"trace_id\":\"acd43b75-f255-471f-9563-f03de03c7e23\"}\n[2026-05-11 11:20:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8ab6728e-9079-4166-bf97-fed4fb2ac7de\",\"trace_id\":\"508ecd6c-81db-47d4-8fad-d40b1e55cff3\"}\n[2026-05-11 11:20:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"8ab6728e-9079-4166-bf97-fed4fb2ac7de\",\"trace_id\":\"508ecd6c-81db-47d4-8fad-d40b1e55cff3\"}\n[2026-05-11 11:20:13] local.NOTICE: Monitoring start {\"correlation_id\":\"98b2a767-ff2a-4f82-866f-bf7dad58fe13\",\"trace_id\":\"ecb25ade-8dda-4d47-8bce-6b84e3c8fd0c\"}\n[2026-05-11 11:20:13] local.NOTICE: Monitoring end {\"correlation_id\":\"98b2a767-ff2a-4f82-866f-bf7dad58fe13\",\"trace_id\":\"ecb25ade-8dda-4d47-8bce-6b84e3c8fd0c\"}\n[2026-05-11 11:20:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"05f19e62-48e4-4c36-9577-648a2dd54abd\",\"trace_id\":\"e3d3acd1-5c23-4f37-9566-32a0cbd7a4eb\"}\n[2026-05-11 11:20:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"05f19e62-48e4-4c36-9577-648a2dd54abd\",\"trace_id\":\"e3d3acd1-5c23-4f37-9566-32a0cbd7a4eb\"}\n[2026-05-11 11:20:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d5c19bc5-1a17-4b6d-9f62-a6715a8005c9\",\"trace_id\":\"451385cf-1bcd-4e06-8412-e5d197f5f567\"}\n[2026-05-11 11:20:18] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d5c19bc5-1a17-4b6d-9f62-a6715a8005c9\",\"trace_id\":\"451385cf-1bcd-4e06-8412-e5d197f5f567\"}\n[2026-05-11 11:20:18] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d5c19bc5-1a17-4b6d-9f62-a6715a8005c9\",\"trace_id\":\"451385cf-1bcd-4e06-8412-e5d197f5f567\"}\n[2026-05-11 11:20:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d5c19bc5-1a17-4b6d-9f62-a6715a8005c9\",\"trace_id\":\"451385cf-1bcd-4e06-8412-e5d197f5f567\"}\n[2026-05-11 11:20:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a01c4c40-1c1e-4865-be1f-0aa63b4fd1b9\",\"trace_id\":\"cba182ec-cbe6-4d53-b1c6-253546138cc8\"}\n[2026-05-11 11:20:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-11 11:18:00, 2026-05-11 11:20:00] {\"correlation_id\":\"a01c4c40-1c1e-4865-be1f-0aa63b4fd1b9\",\"trace_id\":\"cba182ec-cbe6-4d53-b1c6-253546138cc8\"}\n[2026-05-11 11:20:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-11 11:18:00, 2026-05-11 11:20:00] {\"correlation_id\":\"a01c4c40-1c1e-4865-be1f-0aa63b4fd1b9\",\"trace_id\":\"cba182ec-cbe6-4d53-b1c6-253546138cc8\"}\n[2026-05-11 11:20:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"a01c4c40-1c1e-4865-be1f-0aa63b4fd1b9\",\"trace_id\":\"cba182ec-cbe6-4d53-b1c6-253546138cc8\"}\n[2026-05-11 11:20:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b599f338-6a44-44d5-9f81-6fa300c4ea1b\",\"trace_id\":\"c7645418-4758-4410-83f2-8fe71ebf2ec2\"}\n[2026-05-11 11:20:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b599f338-6a44-44d5-9f81-6fa300c4ea1b\",\"trace_id\":\"c7645418-4758-4410-83f2-8fe71ebf2ec2\"}\n[2026-05-11 11:20:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3c9d7674-d005-4372-8a60-2e8ecb587584\",\"trace_id\":\"22a0bdee-d653-4113-963c-043a68a4a8be\"}\n[2026-05-11 11:20:29] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"3c9d7674-d005-4372-8a60-2e8ecb587584\",\"trace_id\":\"22a0bdee-d653-4113-963c-043a68a4a8be\"}\n[2026-05-11 11:20:31] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"1453203b-bac8-47ba-ac62-6369ac533fc2\",\"trace_id\":\"f176800e-9da8-4580-a332-56fa3402dbb7\"}\n[2026-05-11 11:20:31] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"1453203b-bac8-47ba-ac62-6369ac533fc2\",\"trace_id\":\"f176800e-9da8-4580-a332-56fa3402dbb7\"}\n[2026-05-11 11:20:31] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"1453203b-bac8-47ba-ac62-6369ac533fc2\",\"trace_id\":\"f176800e-9da8-4580-a332-56fa3402dbb7\"}\n[2026-05-11 11:20:33] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2310f110-1f7e-4a28-b0c3-e5f8fc72688f\",\"trace_id\":\"9d6e8217-2f4e-4b23-8f36-8538f57064d9\"}\n[2026-05-11 11:20:33] local.INFO: Running conference:monitor:start command for activities in (2026-05-11 11:10:00, 2026-05-11 11:15:00] {\"correlation_id\":\"2310f110-1f7e-4a28-b0c3-e5f8fc72688f\",\"trace_id\":\"9d6e8217-2f4e-4b23-8f36-8538f57064d9\"}\n[2026-05-11 11:20:33] local.INFO: [conference:monitor:start] No activities found in (2026-05-11 11:10:00, 2026-05-11 11:15:00] {\"correlation_id\":\"2310f110-1f7e-4a28-b0c3-e5f8fc72688f\",\"trace_id\":\"9d6e8217-2f4e-4b23-8f36-8538f57064d9\"}\n[2026-05-11 11:20:33] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2310f110-1f7e-4a28-b0c3-e5f8fc72688f\",\"trace_id\":\"9d6e8217-2f4e-4b23-8f36-8538f57064d9\"}\n[2026-05-11 11:20:37] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"48a2dc23-76e1-4b34-b8a7-a7a957c71373\",\"trace_id\":\"b1788ca3-54cf-4031-b198-102838446996\"}\n[2026-05-11 11:20:37] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"11:15\",\"to\":\"11:20\"} {\"correlation_id\":\"48a2dc23-76e1-4b34-b8a7-a7a957c71373\",\"trace_id\":\"b1788ca3-54cf-4031-b198-102838446996\"}\n[2026-05-11 11:20:38] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"01:10\",\"to\":\"01:15\"} {\"correlation_id\":\"48a2dc23-76e1-4b34-b8a7-a7a957c71373\",\"trace_id\":\"b1788ca3-54cf-4031-b198-102838446996\"}\n[2026-05-11 11:20:38] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"48a2dc23-76e1-4b34-b8a7-a7a957c71373\",\"trace_id\":\"b1788ca3-54cf-4031-b198-102838446996\"}\n[2026-05-11 11:20:41] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.ERROR: Failed to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.ERROR: Failed to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:42] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:43] local.ERROR: Failed to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:43] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"cb985c75-d47d-45c5-a37a-f6f0c95026fd\",\"trace_id\":\"bde7c5d1-1c73-488b-a11c-a2c8701ef310\"}\n[2026-05-11 11:20:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"jiminny:transcription:retry-failed\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"28cf48be-a629-420c-a0a4-0d20fbd05838\",\"trace_id\":\"4fdaba19-5d8e-45db-a600-da048c8066fb\"}\n[2026-05-11 11:20:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6a6c06af-94cf-46bf-976e-55e401b3a588\",\"trace_id\":\"338c3b84-fc5a-404b-bed6-97341331ae68\"}\n[2026-05-11 11:20:48] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"954d156d-8a4f-4592-a046-e16c5dd7d3bf\",\"trace_id\":\"ecc7aeb5-a4e6-4a0d-9ebd-4aeb260f5d55\"}\n[2026-05-11 11:20:48] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":60.0} {\"correlation_id\":\"954d156d-8a4f-4592-a046-e16c5dd7d3bf\",\"trace_id\":\"ecc7aeb5-a4e6-4a0d-9ebd-4aeb260f5d55\"}\n[2026-05-11 11:20:48] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-11T11:22:48.807561Z\"} {\"correlation_id\":\"954d156d-8a4f-4592-a046-e16c5dd7d3bf\",\"trace_id\":\"ecc7aeb5-a4e6-4a0d-9ebd-4aeb260f5d55\"}\n[2026-05-11 11:20:48] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"954d156d-8a4f-4592-a046-e16c5dd7d3bf\",\"trace_id\":\"ecc7aeb5-a4e6-4a0d-9ebd-4aeb260f5d55\"}\n[2026-05-11 11:20:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"jiminny:transcription:retry-failed\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"28cf48be-a629-420c-a0a4-0d20fbd05838\",\"trace_id\":\"4fdaba19-5d8e-45db-a600-da048c8066fb\"}\n[2026-05-11 11:20:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6a6c06af-94cf-46bf-976e-55e401b3a588\",\"trace_id\":\"338c3b84-fc5a-404b-bed6-97341331ae68\"}\n[2026-05-11 11:20:49] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"954d156d-8a4f-4592-a046-e16c5dd7d3bf\",\"trace_id\":\"ecc7aeb5-a4e6-4a0d-9ebd-4aeb260f5d55\"}\n[2026-05-11 11:20:49] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"954d156d-8a4f-4592-a046-e16c5dd7d3bf\",\"trace_id\":\"ecc7aeb5-a4e6-4a0d-9ebd-4aeb260f5d55\"}\n[2026-05-11 11:20:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c8d52370-b908-428c-b973-699db0be2136\",\"trace_id\":\"fabc1f54-e263-4ba0-b8ff-324f62e84f1f\"}\n[2026-05-11 11:20:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c8d52370-b908-428c-b973-699db0be2136\",\"trace_id\":\"fabc1f54-e263-4ba0-b8ff-324f62e84f1f\"}\n[2026-05-11 11:20:54] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"954d156d-8a4f-4592-a046-e16c5dd7d3bf\",\"trace_id\":\"ecc7aeb5-a4e6-4a0d-9ebd-4aeb260f5d55\"}\n[2026-05-11 11:20:56] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"de84a4c9-d2c5-4950-8c2d-f400cee667bf\",\"trace_id\":\"223fd9b2-ed24-4083-98cd-1bc4040dbbd1\"}\n[2026-05-11 11:20:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":60.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"de84a4c9-d2c5-4950-8c2d-f400cee667bf\",\"trace_id\":\"223fd9b2-ed24-4083-98cd-1bc4040dbbd1\"}\n[2026-05-11 11:20:59] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"954d156d-8a4f-4592-a046-e16c5dd7d3bf\",\"trace_id\":\"ecc7aeb5-a4e6-4a0d-9ebd-4aeb260f5d55\"}","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}]...
|
-6130832161103967245
|
6799670464363641057
|
idle
|
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 Jiminny\Exceptions;
use Throwable;
class RateLimitException extends RuntimeException
{
public function __construct(
string $message = '',
private readonly int $retryAfter = 1,
?Throwable $previous = null,
) {
parent::__construct($message, 0, $previous);
}
public function getRetryAfter(): int
{
return max($this->retryAfter, 1);
}
}
Show Replace Field
Search History
429
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
23/38
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
454
Previous Highlighted Error
Next Highlighted Error
[2026-05-11 11:17:21] local.NOTICE: Monitoring start {"correlation_id":"885fde59-3852-4120-a620-af3da7ecce17","trace_id":"4cc10f53-5d39-418d-8e98-fe53d9bbff5f"}
[2026-05-11 11:17:21] local.NOTICE: Monitoring end {"correlation_id":"885fde59-3852-4120-a620-af3da7ecce17","trace_id":"4cc10f53-5d39-418d-8e98-fe53d9bbff5f"}
[2026-05-11 11:17:34] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":60.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a773fb28-5a0c-4b8f-a1b5-d57e6b81db90","trace_id":"fb6d8028-db7d-4ef2-b175-740f0a7b8b39"}
[2026-05-11 11:17:35] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":60.0,"memoryAfterCommandInMB":60.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"a773fb28-5a0c-4b8f-a1b5-d57e6b81db90","trace_id":"fb6d8028-db7d-4ef2-b175-740f0a7b8b39"}
[2026-05-11 11:17:37] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":615092,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":null,"account_id":26,"opportunity_id":22,"stage_id":89}} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:37] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":615092} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:37] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":615092,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:37] local.INFO: [MatchActivityCrmData] Participants old state {"activity":615092,"participants":[{"id":1004102,"user_id":null,"contact_id":null,"lead_id":null},{"id":1004103,"user_id":89,"contact_id":null,"lead_id":null}]} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:37] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:37] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:37] local.INFO: [Prospect match] Cache miss, calling the API {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [Hubspot] Failed to fetch contact {"email":"[EMAIL]","reason":"[404] Client error: `GET https://api.hubapi.com/crm/v3/objects/contacts/nikolay.nikolov%40jiminny.com?properties=email%2Cfirstname%2Clastname%2Ccountry%2Cphone%2Cmobilephone%2Cjobtitle%2Chubspot_owner_id%2Cassociatedcompanyid%2Cphoto&archived=0&idProperty=email` resulted in a `404 Not Found` response"} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [Prospect match] API returned empty result, caching the miss with empty prospect data {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.WARNING: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":1,"reason":"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\":\"019e16c1-c (truncated...)
"} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {"job_class":"Jiminny\\Jobs\\Crm\\MatchActivityCrmData","attempts":1,"retry_after":1,"delay":4} {"correlation_id":"01554272-3758-416d-bcd8-0b07cf17fce3","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":614436,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":null,"account_id":26,"opportunity_id":22,"stage_id":89}} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":614436} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":614436,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [MatchActivityCrmData] Participants old state {"activity":614436,"participants":[{"id":1002751,"user_id":null,"contact_id":null,"lead_id":null},{"id":1002752,"user_id":89,"contact_id":null,"lead_id":null}]} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:38] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {"job_class":"Jiminny\\Jobs\\Crm\\MatchActivityCrmData","attempts":1,"retry_after":1,"delay":3} {"correlation_id":"6f97c580-31f1-4723-80d8-b1046a615d37","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":614382,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":null,"account_id":26,"opportunity_id":22,"stage_id":89}} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":614382} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":614382,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Participants old state {"activity":614382,"participants":[{"id":1002632,"user_id":null,"contact_id":null,"lead_id":null},{"id":1002633,"user_id":89,"contact_id":null,"lead_id":null}]} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {"job_class":"Jiminny\\Jobs\\Crm\\MatchActivityCrmData","attempts":1,"retry_after":1,"delay":1} {"correlation_id":"80fe8576-047a-495f-b42a-d75cb83d9591","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":614381,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":null,"account_id":26,"opportunity_id":22,"stage_id":89}} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":614381} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":614381,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Participants old state {"activity":614381,"participants":[{"id":1002630,"user_id":null,"contact_id":null,"lead_id":null},{"id":1002631,"user_id":89,"contact_id":null,"lead_id":null}]} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.WARNING: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":1,"reason":"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\":\"019e16c1-c (truncated...)
"} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {"job_class":"Jiminny\\Jobs\\Crm\\MatchActivityCrmData","attempts":1,"retry_after":1,"delay":2} {"correlation_id":"55cd98de-2b2f-4dd6-b0d5-36af698ea32d","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":614378,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":6167,"account_id":null,"opportunity_id":null,"stage_id":null}} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":614378} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":614378,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [MatchActivityCrmData] Participants old state {"activity":614378,"participants":[{"id":1002623,"user_id":null,"contact_id":null,"lead_id":null},{"id":1002624,"user_id":null,"contact_id":6167,"lead_id":null},{"id":1002625,"user_id":89,"contact_id":null,"lead_id":null}]} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:39] local.INFO: [Prospect match] cached empty result - no API calls, try next matching method {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [HandleHubspotRateLimit] Rate limit caught, releasing job with delay {"job_class":"Jiminny\\Jobs\\Crm\\MatchActivityCrmData","attempts":1,"retry_after":1,"delay":3} {"correlation_id":"05cfe3c8-6fd4-4a49-ab3c-70dfd05e457b","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":613840,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36}} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613840} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613840,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {"activity":613840,"participants":[{"id":1001764,"user_id":null,"contact_id":4487,"lead_id":null},{"id":1001765,"user_id":261,"contact_id":null,"lead_id":null}]} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: ProspectCache - Searching DB for opportunity by owner {"account_id":244,"contact_id":4487,"owner_id":261} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: ProspectCache - Opportunity DB search results {"account_id":244,"contact_id":4487,"opportunity_id":299} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":613840,"team_id":2,"email":"[EMAIL]"} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {"activity_id":613840,"participants_processed":2,"exact_matches":1,"domain_matches":0,"best_match_found":true} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613840} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613840,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {"activity":613840,"remote_search":true,"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36} {"correlation_id":"8ccfe9b2-ef68-4a3d-95a5-5ca1667f2a59","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":613833,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36}} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613833} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613833,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {"activity":613833,"participants":[{"id":1001750,"user_id":null,"contact_id":4487,"lead_id":null},{"id":1001751,"user_id":261,"contact_id":null,"lead_id":null}]} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateProcessManager ] Finished updating entities in ES {"worker":"","peak_memory":"99.73 MB","elapsed_seconds":1.0,"update_target":"activities","should_iterate_again":false} {"correlation_id":"8c24420c-db53-4450-9cd8-db5d2426bd57","trace_id":"5406d133-f6cd-4f5a-b463-9146e1dfb021"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":613833,"team_id":2,"email":"[EMAIL]"} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {"activity_id":613833,"participants_processed":2,"exact_matches":1,"domain_matches":0,"best_match_found":true} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613833} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613833,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {"activity":613833,"remote_search":true,"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36} {"correlation_id":"41fb906c-1cf1-4cdb-b1bd-c638f6abc0fe","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":613827,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36}} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613827} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613827,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {"activity":613827,"participants":[{"id":1001734,"user_id":null,"contact_id":4487,"lead_id":null},{"id":1001735,"user_id":261,"contact_id":null,"lead_id":null}]} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":613827,"team_id":2,"email":"[EMAIL]"} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {"activity_id":613827,"participants_processed":2,"exact_matches":1,"domain_matches":0,"best_match_found":true} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613827} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613827,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {"activity":613827,"remote_search":true,"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36} {"correlation_id":"d1d42ab0-5c87-42e8-a91f-a56b538619ce","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":613826,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36}} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613826} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613826,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {"activity":613826,"participants":[{"id":1001732,"user_id":null,"contact_id":4487,"lead_id":null},{"id":1001733,"user_id":261,"contact_id":null,"lead_id":null}]} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":613826,"team_id":2,"email":"[EMAIL]"} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {"activity_id":613826,"participants_processed":2,"exact_matches":1,"domain_matches":0,"best_match_found":true} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613826} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613826,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {"activity":613826,"remote_search":true,"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36} {"correlation_id":"861e79c7-b5d3-4476-b429-0f1b4cf196a4","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":613820,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36}} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613820} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613820,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {"activity":613820,"participants":[{"id":1001721,"user_id":null,"contact_id":4487,"lead_id":null},{"id":1001722,"user_id":261,"contact_id":null,"lead_id":null}]} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":613820,"team_id":2,"email":"[EMAIL]"} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [CrmActivityService] CRM matching completed {"activity_id":613820,"participants_processed":2,"exact_matches":1,"domain_matches":0,"best_match_found":true} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613820} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613820,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {"activity":613820,"remote_search":true,"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36} {"correlation_id":"97a99ff2-5956-4d77-837b-790c01b09967","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":613818,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36}} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613818} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613818,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:40] local.INFO: [MatchActivityCrmData] Participants old state {"activity":613818,"participants":[{"id":1001717,"user_id":null,"contact_id":4487,"lead_id":null},{"id":1001718,"user_id":261,"contact_id":null,"lead_id":null}]} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":613818,"team_id":2,"email":"[EMAIL]"} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [CrmActivityService] CRM matching completed {"activity_id":613818,"participants_processed":2,"exact_matches":1,"domain_matches":0,"best_match_found":true} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613818} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613818,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {"activity":613818,"remote_search":true,"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36} {"correlation_id":"300f80c3-6a45-4372-85a9-9fe439206596","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":613812,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36}} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613812} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613812,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Participants old state {"activity":613812,"participants":[{"id":1001705,"user_id":null,"contact_id":4487,"lead_id":null},{"id":1001706,"user_id":261,"contact_id":null,"lead_id":null}]} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [Prospect match] Cache / local search hit {"identifier_type":"email","identifier":"[EMAIL]"} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":613812,"team_id":2,"email":"[EMAIL]"} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [CrmActivityService] CRM matching completed {"activity_id":613812,"participants_processed":2,"exact_matches":1,"domain_matches":0,"best_match_found":true} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613812} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613812,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Successfully matched CRM data {"activity":613812,"remote_search":true,"lead_id":null,"contact_id":4487,"account_id":244,"opportunity_id":299,"stage_id":36} {"correlation_id":"7a348156-9d36-4f25-ad5e-4fbfce8fd82a","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":613807,"remote_search":true,"set_configuration":2,"old_state":{"lead_id":null,"contact_id":4484,"account_id":243,"opportunity_id":276,"stage_id":36}} {"correlation_id":"499c94c1-2716-49a2-9cdf-d5eb84f68ac6","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":613807} {"correlation_id":"499c94c1-2716-49a2-9cdf-d5eb84f68ac6","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":613807,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"499c94c1-2716-49a2-9cdf-d5eb84f68ac6","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [MatchActivityCrmData] Participants old state {"activity":613807,"participants":[{"id":1001690,"user_id":253,"contact_id":null,"lead_id":null},{"id":1001691,"user_id":null,"contact_id":4484,"lead_id":null}]} {"correlation_id":"499c94c1-2716-49a2-9cdf-d5eb84f68ac6","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"499c94c1-2716-49a2-9cdf-d5eb84f68ac6","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"499c94c1-2716-49a2-9cdf-d5eb84f68ac6","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"499c94c1-2716-49a2-9cdf-d5eb84f68ac6","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"499c94c1-2716-49a2-9cdf-d5eb84f68ac6","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":613807,"team_id":2,"email":"[EMAIL]"} {"correlation_id":"499c94c1-2716-49a2-9cdf-d5eb84f68ac6","trace_id":"6cee2988-85fe-44ce-ba47-56fc0392669c"}
[2026-05-11 11:17:41] local.INFO: ProspectCache - Searching DB for opportunity by owner {"account_id"...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
18742
|
805
|
40
|
2026-05-11T11:43:16.985038+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778499796985_m2.jpg...
|
Code
|
Claude Code — 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
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
SyncTeamFieldsJob.php
SyncTeamMetadata.php
UpdateOpportunitySpecifications.php
UpdateStage.php
DealRisks
Mailbox
MeetingBot
Middleware
HandleHubspotRateLimit.php
M
RateLimited.php
Streaming
Team
Telephony
User
BaseProcessingJob.php
DummyJob.php
ImportRecallAIRecordingsJob.php
ImportRemoteTrackJob.php
Job.php
JobDispatcher.php
JobDispatcherInterface.php
PurgeSoftDeletedOpportunityJob.php
SqsVisibilityControl.php
Listeners
Mail
Models
Activity
Ai
AskAnything
Calendar
...
|
[{"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":27,"bounds":{"left":0.026595745,"top":0.0933759,"width":0.0063164895,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"CheckAndRetryRemoteMatch.php","depth":27,"bounds":{"left":0.033909574,"top":0.0933759,"width":0.068484046,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.0933759,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":27,"bounds":{"left":0.036901597,"top":0.0933759,"width":0.06549202,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.10853951,"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.110135674,"width":0.054853722,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.11093376,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":25,"bounds":{"left":0.036901597,"top":0.11093376,"width":0.051861703,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.12609737,"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.12769353,"width":0.034242023,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.12849163,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":14,"bounds":{"left":0.036901597,"top":0.12849163,"width":0.03125,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.14365523,"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.1452514,"width":0.07712766,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.14604948,"width":0.0039893617,"height":0.011971269}},{"char_start":1,"char_count":34,"bounds":{"left":0.037898935,"top":0.14604948,"width":0.07347074,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.16121309,"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.16280925,"width":0.054521278,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.16360734,"width":0.0039893617,"height":0.011971269}},{"char_start":1,"char_count":23,"bounds":{"left":0.037898935,"top":0.16360734,"width":0.050531916,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":27,"bounds":{"left":0.10638298,"top":0.16360734,"width":0.003656915,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.17877094,"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.18036711,"width":0.031914894,"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":13,"bounds":{"left":0.03723404,"top":0.1811652,"width":0.028922873,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.1963288,"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.19792499,"width":0.03324468,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.19872306,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":15,"bounds":{"left":0.03656915,"top":0.19872306,"width":0.030585106,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.21388668,"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.21548285,"width":0.04454787,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.21628092,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":20,"bounds":{"left":0.03656915,"top":0.21628092,"width":0.042220745,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.23144454,"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.2330407,"width":0.034242023,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.23383878,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":14,"bounds":{"left":0.03656915,"top":0.23383878,"width":0.031914894,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.2490024,"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.25059855,"width":0.03357713,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.25139666,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":15,"bounds":{"left":0.03656915,"top":0.25139666,"width":0.030917553,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.26656026,"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.26815644,"width":0.047539894,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.26895452,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":20,"bounds":{"left":0.03656915,"top":0.26895452,"width":0.04488032,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.28411812,"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.2857143,"width":0.051861703,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.28651237,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":21,"bounds":{"left":0.03656915,"top":0.28651237,"width":0.04920213,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.30167598,"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.30327216,"width":0.030917553,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.30407023,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":12,"bounds":{"left":0.03656915,"top":0.30407023,"width":0.02825798,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.31923383,"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.32083002,"width":0.034574468,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.3216281,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":14,"bounds":{"left":0.03656915,"top":0.3216281,"width":0.031914894,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.3367917,"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.33838788,"width":0.053856384,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.33918595,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":23,"bounds":{"left":0.03656915,"top":0.33918595,"width":0.05119681,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.35434955,"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.35594574,"width":0.04288564,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.3567438,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":18,"bounds":{"left":0.03656915,"top":0.3567438,"width":0.040226065,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.3719074,"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.3735036,"width":0.05086436,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.37430167,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":22,"bounds":{"left":0.03656915,"top":0.37430167,"width":0.048204787,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.38946527,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncTeamFieldsJob.php","depth":27,"bounds":{"left":0.033909574,"top":0.39106146,"width":0.04886968,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.39185953,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":20,"bounds":{"left":0.03656915,"top":0.39185953,"width":0.046210106,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.40702313,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncTeamMetadata.php","depth":27,"bounds":{"left":0.033909574,"top":0.4086193,"width":0.048537236,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.4094174,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":19,"bounds":{"left":0.03656915,"top":0.4094174,"width":0.045877658,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.026595745,"top":0.424581,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"UpdateOpportunitySpecifications.php","depth":27,"bounds":{"left":0.033909574,"top":0.42617717,"width":0.076130316,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.42697525,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":34,"bounds":{"left":0.03723404,"top":0.42697525,"width":0.0731383,"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":"UpdateStage.php","depth":27,"bounds":{"left":0.033909574,"top":0.44373503,"width":0.03523936,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.4445331,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":14,"bounds":{"left":0.03723404,"top":0.4445331,"width":0.032247342,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.4612929,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":27,"bounds":{"left":0.03125,"top":0.4612929,"width":0.019614361,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.46209097,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":8,"bounds":{"left":0.034574468,"top":0.46209097,"width":0.016289894,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.47885075,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Mailbox","depth":27,"bounds":{"left":0.03125,"top":0.47885075,"width":0.015625,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.47964883,"width":0.0039893617,"height":0.011971269}},{"char_start":1,"char_count":6,"bounds":{"left":0.03523936,"top":0.47964883,"width":0.011635638,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.4964086,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot","depth":27,"bounds":{"left":0.03125,"top":0.4964086,"width":0.023271276,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.49720672,"width":0.0039893617,"height":0.011971269}},{"char_start":1,"char_count":9,"bounds":{"left":0.03523936,"top":0.49720672,"width":0.019281914,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.5139665,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Middleware","depth":27,"bounds":{"left":0.03125,"top":0.5139665,"width":0.023271276,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.51476455,"width":0.0039893617,"height":0.011971269}},{"char_start":1,"char_count":9,"bounds":{"left":0.03523936,"top":0.51476455,"width":0.019281914,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.10605053,"top":0.51476455,"width":0.004654255,"height":0.011173184},"on_screen":true,"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":"HandleHubspotRateLimit.php","depth":27,"bounds":{"left":0.033909574,"top":0.53152436,"width":0.059175532,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.5323224,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":25,"bounds":{"left":0.03723404,"top":0.5323224,"width":0.05618351,"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":"RateLimited.php","depth":27,"bounds":{"left":0.033909574,"top":0.5490822,"width":0.032912236,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.033909574,"top":0.54988027,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":14,"bounds":{"left":0.036901597,"top":0.54988027,"width":0.029920213,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.5666401,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Streaming","depth":27,"bounds":{"left":0.03125,"top":0.5666401,"width":0.020611702,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.5674381,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":8,"bounds":{"left":0.033909574,"top":0.5674381,"width":0.017952127,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.58419794,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Team","depth":27,"bounds":{"left":0.03125,"top":0.58419794,"width":0.010970744,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.584996,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":3,"bounds":{"left":0.03357713,"top":0.584996,"width":0.008643617,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.6017558,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Telephony","depth":27,"bounds":{"left":0.03125,"top":0.6017558,"width":0.020611702,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.60255384,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":8,"bounds":{"left":0.03357713,"top":0.60255384,"width":0.018284574,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.61931366,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"User","depth":27,"bounds":{"left":0.03125,"top":0.61931366,"width":0.00930851,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.6201117,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":3,"bounds":{"left":0.034574468,"top":0.6201117,"width":0.0063164895,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.023936171,"top":0.63527536,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"BaseProcessingJob.php","depth":27,"bounds":{"left":0.03125,"top":0.6368715,"width":0.048537236,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.63766956,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":20,"bounds":{"left":0.034242023,"top":0.63766956,"width":0.045545213,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.023936171,"top":0.6528332,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"DummyJob.php","depth":27,"bounds":{"left":0.03125,"top":0.6544294,"width":0.03158245,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.6552275,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":11,"bounds":{"left":0.034574468,"top":0.6552275,"width":0.02825798,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.023936171,"top":0.6703911,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ImportRecallAIRecordingsJob.php","depth":27,"bounds":{"left":0.03125,"top":0.67198724,"width":0.068484046,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.67278534,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":30,"bounds":{"left":0.032579787,"top":0.67278534,"width":0.06715426,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.023936171,"top":0.68794894,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ImportRemoteTrackJob.php","depth":27,"bounds":{"left":0.03125,"top":0.6895451,"width":0.055518616,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.6903432,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":23,"bounds":{"left":0.032579787,"top":0.6903432,"width":0.054521278,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.023936171,"top":0.7055068,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Job.php","depth":27,"bounds":{"left":0.03125,"top":0.70710295,"width":0.016289894,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.70790106,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":6,"bounds":{"left":0.03357713,"top":0.70790106,"width":0.014295213,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.023936171,"top":0.72306466,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JobDispatcher.php","depth":27,"bounds":{"left":0.03125,"top":0.7246608,"width":0.037898935,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.7254589,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":16,"bounds":{"left":0.03357713,"top":0.7254589,"width":0.035904255,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.023936171,"top":0.7406225,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JobDispatcherInterface.php","depth":27,"bounds":{"left":0.03125,"top":0.7422187,"width":0.05618351,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.7430168,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":25,"bounds":{"left":0.03357713,"top":0.7430168,"width":0.05418883,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.023936171,"top":0.7581804,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"PurgeSoftDeletedOpportunityJob.php","depth":27,"bounds":{"left":0.03125,"top":0.75977653,"width":0.076130316,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.023936171,"top":0.77573824,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SqsVisibilityControl.php","depth":27,"bounds":{"left":0.03125,"top":0.7773344,"width":0.047872342,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.022273935,"top":0.79489225,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Listeners","depth":27,"bounds":{"left":0.028590426,"top":0.79489225,"width":0.018284574,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.022273935,"top":0.8124501,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Mail","depth":27,"bounds":{"left":0.028590426,"top":0.8124501,"width":0.00831117,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.022273935,"top":0.830008,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Models","depth":27,"bounds":{"left":0.028590426,"top":0.830008,"width":0.01462766,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.8475658,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":27,"bounds":{"left":0.03125,"top":0.8475658,"width":0.014960106,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.8651237,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Ai","depth":27,"bounds":{"left":0.03125,"top":0.8651237,"width":0.0039893617,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.88268155,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":27,"bounds":{"left":0.03125,"top":0.88268155,"width":0.025265958,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.9002394,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Calendar","depth":27,"bounds":{"left":0.03125,"top":0.9002394,"width":0.017952127,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.91779727,"width":0.005319149,"height":0.011971269},"on_screen":true,"role_description":"text"}]...
|
2636384380862741095
|
8816674118460834122
|
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
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
SyncTeamFieldsJob.php
SyncTeamMetadata.php
UpdateOpportunitySpecifications.php
UpdateStage.php
DealRisks
Mailbox
MeetingBot
Middleware
HandleHubspotRateLimit.php
M
RateLimited.php
Streaming
Team
Telephony
User
BaseProcessingJob.php
DummyJob.php
ImportRecallAIRecordingsJob.php
ImportRemoteTrackJob.php
Job.php
JobDispatcher.php
JobDispatcherInterface.php
PurgeSoftDeletedOpportunityJob.php
SqsVisibilityControl.php
Listeners
Mail
Models
Activity
Ai
AskAnything
Calendar
...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
18910
|
811
|
40
|
2026-05-11T11:59:49.029471+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778500789029_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
Handler.php
HttpBadRequestException.php
HttpBadRequestWithErrorReasonException.php
HttpForbiddenException.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":27,"bounds":{"left":0.023936171,"top":0.0933759,"width":0.0063164895,"height":0.003990423},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Handler.php","depth":27,"bounds":{"left":0.03125,"top":0.0933759,"width":0.024601065,"height":0.0023942539},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.023936171,"top":0.09976058,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HttpBadRequestException.php","depth":27,"bounds":{"left":0.03125,"top":0.101356745,"width":0.061835106,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.10215483,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":26,"bounds":{"left":0.034574468,"top":0.10215483,"width":0.058843084,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.023936171,"top":0.11731844,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HttpBadRequestWithErrorReasonException.php","depth":27,"bounds":{"left":0.03125,"top":0.118914604,"width":0.08277926,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.11971269,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":41,"bounds":{"left":0.034574468,"top":0.11971269,"width":0.09275266,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.023936171,"top":0.1348763,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HttpForbiddenException.php","depth":27,"bounds":{"left":0.03125,"top":0.13647246,"width":0.05817819,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.13727055,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":25,"bounds":{"left":0.034574468,"top":0.13727055,"width":0.054853722,"height":0.011971269}}],"role_description":"text"}]...
|
7266449563733020850
|
-695005969058429688
|
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
Handler.php
HttpBadRequestException.php
HttpBadRequestWithErrorReasonException.php
HttpForbiddenException.php...
|
18908
|
NULL
|
NULL
|
NULL
|
|
19286
|
827
|
40
|
2026-05-11T12:41:00.696249+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778503260696_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 [URL_WITH_CREDENTIALS]
Add a title
*
JY-20725 add HS rate limit handling on activities rematching
Generate pull request title with Copilot
Add a description
Add a description
Comment
Write
Write
Preview
Preview
### JIRA: JY-20725
#### Changes:
- Adds HandleHubspotRateLimit middleware
- Add
Markdown is supported
Markdown
is supported
Paste, drop, or click to add files
Paste, drop, or click to add files
Create pull request
Select a type of pull request
Remember, contributions to this repository should follow our
GitHub Community Guidelines
GitHub Community Guidelines
.
️
Reviewers
Suggestions
Request
Request
@yalokin-jiminny
yalokin-jiminny
yalokin-jiminny
Request
Request
@nikolaybiaivanov
nikolaybiaivanov
nikolaybiaivanov
Request
Request
@ivhristova
ivhristova
ivhristova
At least 1 approving review is required to merge this pull request.
Assignees
No one—
assign yourself
Labels
None yet
Projects
None yet
Milestone
No milestone
Helpful resources
GitHub Community Guidelines
GitHub Community Guidelines
1
commit
9
files changed
1
contributor
Commits on May 11, 2026
Commits on May 11, 2026
JY-20725
JY-20725
add HS rate limit handling on activities rematching
add HS rate limit handling on activities rematching
@LakyLak
LakyLak
LakyLak
committed
3 minutes ago
3 / 6 checks OK
Copy the full SHA
44d5678
44d5678
Browse the repository at this point in the history
Split
Split
Unified
Unified
Showing
9 changed files
with
461 additions
and
22 deletions
.
Toggle diff contents
Expand all
16 changes: 15 additions & 1 deletion
app/Exceptions/RateLimitException.php
app/Exceptions/RateLimitException.php
Copy
Show options
Original file line number
Original file line
Diff line number
Diff line change
Expand Up
@@ -4,6 +4,20 @@
4
4
5
namespace
Jiminny
\
Exceptions
;
5
namespace
Jiminny
\
Exceptions
;
6
6
7
-
class
RateLimitException
extends
LogicException
7
+
use
Throwable
;
8
+
9
+
class
RateLimitException
extends
RuntimeException
8
{...
|
[{"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,"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 (33)","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":"33","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":"Comparing changes","depth":9,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Comparing changes","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"compare across forks","depth":10,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"or","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"learn more about diff comparisons","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"learn more about diff comparisons","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":"base: master","depth":11,"on_screen":false,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"base:","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"master","depth":14,"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":"compare: JY-20725-handle-HS-search-rate-limit","depth":11,"on_screen":false,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"compare:","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-20725-handle-HS-search-rate-limit","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Able to merge.","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"These branches can be automatically merged.","depth":10,"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":"AXStaticText","text":"Add a title","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"JY-20725 add HS rate limit handling on activities rematching","depth":15,"on_screen":false,"value":"JY-20725 add HS rate limit handling on activities rematching","help_text":"","placeholder":"Title","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Generate pull request title with Copilot","depth":16,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Add a description","depth":12,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Add a description","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Comment","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Write","depth":13,"on_screen":false,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Write","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Preview","depth":13,"on_screen":false,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Preview","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"### JIRA: JY-20725\n\n#### Changes:\n\n- Adds HandleHubspotRateLimit middleware\n- Add","depth":15,"on_screen":false,"value":"### JIRA: JY-20725\n\n#### Changes:\n\n- Adds HandleHubspotRateLimit middleware\n- Add","placeholder":" ","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXLink","text":"Markdown is supported","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Markdown","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"is supported","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Paste, drop, or click to add files","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Paste, drop, or click to add files","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create pull request","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Select a type of pull request","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Remember, contributions to this repository should follow our","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub Community Guidelines","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub Community Guidelines","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":"️","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reviewers","depth":12,"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":"Suggestions","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Request","depth":13,"on_screen":false,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Request","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"yalokin-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":"yalokin-jiminny","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Request","depth":13,"on_screen":false,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Request","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@nikolaybiaivanov","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"nikolaybiaivanov","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Request","depth":13,"on_screen":false,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Request","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@ivhristova","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"ivhristova","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ivhristova","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"At least 1 approving review is required to merge this pull request.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Assignees","depth":12,"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":"No one—","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"assign yourself","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Labels","depth":11,"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":"None yet","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Projects","depth":12,"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":"None yet","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Milestone","depth":12,"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":"No milestone","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Helpful resources","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub Community Guidelines","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub Community Guidelines","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commit","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"files changed","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"contributor","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Commits on May 11, 2026","depth":10,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Commits on May 11, 2026","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20725","depth":13,"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":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"add HS rate limit handling on activities rematching","depth":13,"on_screen":false,"help_text":"","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":14,"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":"LakyLak","depth":13,"on_screen":false,"help_text":"View all commits by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"committed","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 minutes ago","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"3 / 6 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":"AXButton","text":"Copy the full SHA","depth":13,"on_screen":false,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"44d5678","depth":13,"on_screen":false,"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":"Browse the repository at this point in the history","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Split","depth":16,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Split","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Unified","depth":16,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Unified","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Showing","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"9 changed files","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"with","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"461 additions","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22 deletions","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":"AXButton","text":"Toggle diff contents","depth":15,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"Expand all","depth":16,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"16 changes: 15 additions & 1 deletion","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app/Exceptions/RateLimitException.php","depth":15,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app/Exceptions/RateLimitException.php","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy","depth":16,"on_screen":false,"help_text":"","role_description":"button","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":"AXStaticText","text":"Original file line number","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Original file line","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Diff line number","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Diff line change","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Expand Up","depth":17,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"@@ -4,6 +4,20 @@","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"namespace","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny","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":"Exceptions","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":"5","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"namespace","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny","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":"Exceptions","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":"6","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7","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":"class","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"RateLimitException","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"extends","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"LogicException","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7","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":"use","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Throwable","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":"8","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":"9","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":"class","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"RateLimitException","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"extends","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"RuntimeException","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8","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"}]...
|
-8193755305135729113
|
6000173288921895822
|
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
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST [URL_WITH_CREDENTIALS]
Add a title
*
JY-20725 add HS rate limit handling on activities rematching
Generate pull request title with Copilot
Add a description
Add a description
Comment
Write
Write
Preview
Preview
### JIRA: JY-20725
#### Changes:
- Adds HandleHubspotRateLimit middleware
- Add
Markdown is supported
Markdown
is supported
Paste, drop, or click to add files
Paste, drop, or click to add files
Create pull request
Select a type of pull request
Remember, contributions to this repository should follow our
GitHub Community Guidelines
GitHub Community Guidelines
.
️
Reviewers
Suggestions
Request
Request
@yalokin-jiminny
yalokin-jiminny
yalokin-jiminny
Request
Request
@nikolaybiaivanov
nikolaybiaivanov
nikolaybiaivanov
Request
Request
@ivhristova
ivhristova
ivhristova
At least 1 approving review is required to merge this pull request.
Assignees
No one—
assign yourself
Labels
None yet
Projects
None yet
Milestone
No milestone
Helpful resources
GitHub Community Guidelines
GitHub Community Guidelines
1
commit
9
files changed
1
contributor
Commits on May 11, 2026
Commits on May 11, 2026
JY-20725
JY-20725
add HS rate limit handling on activities rematching
add HS rate limit handling on activities rematching
@LakyLak
LakyLak
LakyLak
committed
3 minutes ago
3 / 6 checks OK
Copy the full SHA
44d5678
44d5678
Browse the repository at this point in the history
Split
Split
Unified
Unified
Showing
9 changed files
with
461 additions
and
22 deletions
.
Toggle diff contents
Expand all
16 changes: 15 additions & 1 deletion
app/Exceptions/RateLimitException.php
app/Exceptions/RateLimitException.php
Copy
Show options
Original file line number
Original file line
Diff line number
Diff line change
Expand Up
@@ -4,6 +4,20 @@
4
4
5
namespace
Jiminny
\
Exceptions
;
5
namespace
Jiminny
\
Exceptions
;
6
6
7
-
class
RateLimitException
extends
LogicException
7
+
use
Throwable
;
8
+
9
+
class
RateLimitException
extends
RuntimeException
8
{...
|
19285
|
NULL
|
NULL
|
NULL
|
|
19359
|
829
|
40
|
2026-05-11T12:43:53.076535+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778503433076_m2.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_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
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
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)...
|
[{"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":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · 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":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"bounds":{"left":0.37034574,"top":0.19393456,"width":0.18816489,"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}]...
|
1024143710433731904
|
-2912409682906582398
|
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
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
19822
|
849
|
40
|
2026-05-11T13:37:35.667001+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778506655667_m2.jpg...
|
Firefox
|
Coverage on New Code - app in Jiminny SonarQube Cl Coverage on New Code - app in Jiminny SonarQube Cloud — Work...
|
True
|
sonarcloud.io/component_measures?id=jiminny_app&am sonarcloud.io/component_measures?id=jiminny_app&pullRequest=12066&metric=new_coverage&view=list...
|
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
Coverage on New Code - app in Jiminny SonarQube Cloud
Coverage on New Code - app in Jiminny SonarQube Cloud
Close tab
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Skip to measure filters
Skip to measure filters
Undock sidebar
Continuous Code Quality
Favorite Projects
Favorite Projects
Assigned Issues
Assigned Issues
Explore
Explore
Search
Product news
1
Help
New...
Account
app
Project
Overview
Overview
Analysis
Summary
Summary
Issues
Issues
Architecture
Architecture
Security hotspots
Security hotspots
Reporting
Measures
Measures
Activity
Activity
Policies
Intended architecture
Intended architecture
Project
Pull Requests 109
Pull Requests
109
Branches 12
Branches
12
Code...
|
[{"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":"Coverage on New Code - app in Jiminny SonarQube Cloud","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":"Coverage on New Code - app in Jiminny SonarQube Cloud","depth":5,"bounds":{"left":0.37034574,"top":0.19393456,"width":0.10139628,"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":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.3570479,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.37034574,"top":0.22665602,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.35987368,"top":0.24980047,"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 main content","depth":7,"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":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Skip to measure filters","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to measure filters","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Undock sidebar","depth":8,"bounds":{"left":0.44065824,"top":0.059856344,"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":"AXLink","text":"Continuous Code Quality","depth":8,"bounds":{"left":0.46060506,"top":0.058260176,"width":0.04936835,"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":"Favorite Projects","depth":11,"bounds":{"left":0.5219415,"top":0.061452515,"width":0.041888297,"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":"Favorite Projects","depth":12,"bounds":{"left":0.52393615,"top":0.06743815,"width":0.037898935,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Assigned Issues","depth":11,"bounds":{"left":0.56648934,"top":0.061452515,"width":0.040724736,"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":"Assigned Issues","depth":12,"bounds":{"left":0.56848407,"top":0.06743815,"width":0.03673537,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore","depth":11,"bounds":{"left":0.60987365,"top":0.061452515,"width":0.020944148,"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":"Explore","depth":12,"bounds":{"left":0.6118683,"top":0.06743815,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search","depth":8,"bounds":{"left":0.9281915,"top":0.061452515,"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":"Product news","depth":8,"bounds":{"left":0.94148934,"top":0.061452515,"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},{"role":"AXStaticText","text":"1","depth":10,"bounds":{"left":0.9481383,"top":0.06384677,"width":0.0019946808,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":8,"bounds":{"left":0.95478725,"top":0.061452515,"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":"New...","depth":8,"bounds":{"left":0.9680851,"top":0.061452515,"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":"Account","depth":8,"bounds":{"left":0.98138297,"top":0.061452515,"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":"app","depth":12,"bounds":{"left":0.45262632,"top":0.111332804,"width":0.008477394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Project","depth":11,"bounds":{"left":0.45262632,"top":0.1264964,"width":0.013297873,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Overview","depth":10,"bounds":{"left":0.43932846,"top":0.15881884,"width":0.07446808,"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":"Overview","depth":12,"bounds":{"left":0.44996676,"top":0.16480447,"width":0.020777926,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Analysis","depth":13,"bounds":{"left":0.44198802,"top":0.19752593,"width":0.015791224,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Summary","depth":13,"bounds":{"left":0.43932846,"top":0.21947326,"width":0.07446808,"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":"Summary","depth":15,"bounds":{"left":0.44996676,"top":0.2254589,"width":0.020944148,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Issues","depth":13,"bounds":{"left":0.43932846,"top":0.2482043,"width":0.07446808,"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":"Issues","depth":15,"bounds":{"left":0.44996676,"top":0.25418994,"width":0.01412899,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Architecture","depth":13,"bounds":{"left":0.43932846,"top":0.27693537,"width":0.07446808,"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":"Architecture","depth":15,"bounds":{"left":0.44996676,"top":0.282921,"width":0.026928192,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security hotspots","depth":13,"bounds":{"left":0.43932846,"top":0.3056664,"width":0.07446808,"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":"Security hotspots","depth":15,"bounds":{"left":0.44996676,"top":0.31165203,"width":0.03856383,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Reporting","depth":13,"bounds":{"left":0.44198802,"top":0.3443735,"width":0.018284574,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Measures","depth":13,"bounds":{"left":0.43932846,"top":0.36632082,"width":0.07446808,"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":"Measures","depth":15,"bounds":{"left":0.44996676,"top":0.37230647,"width":0.022273935,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Activity","depth":13,"bounds":{"left":0.43932846,"top":0.39505187,"width":0.07446808,"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":"Activity","depth":15,"bounds":{"left":0.44996676,"top":0.4010375,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Policies","depth":13,"bounds":{"left":0.44198802,"top":0.43375897,"width":0.014461436,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Intended architecture","depth":13,"bounds":{"left":0.43932846,"top":0.4557063,"width":0.07446808,"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":"Intended architecture","depth":15,"bounds":{"left":0.44996676,"top":0.46169195,"width":0.047041222,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Project","depth":13,"bounds":{"left":0.44198802,"top":0.4944134,"width":0.013297873,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull Requests 109","depth":13,"bounds":{"left":0.43932846,"top":0.51636076,"width":0.07446808,"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":"Pull Requests","depth":15,"bounds":{"left":0.44996676,"top":0.5223464,"width":0.029587766,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"109","depth":15,"bounds":{"left":0.50299203,"top":0.5231444,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Branches 12","depth":13,"bounds":{"left":0.43932846,"top":0.5450918,"width":0.07446808,"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":"Branches","depth":15,"bounds":{"left":0.44996676,"top":0.5510774,"width":0.020777926,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12","depth":15,"bounds":{"left":0.5056516,"top":0.5518755,"width":0.004155585,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":13,"bounds":{"left":0.43932846,"top":0.5738228,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
6064109127812762778
|
9030877866353728138
|
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
Coverage on New Code - app in Jiminny SonarQube Cloud
Coverage on New Code - app in Jiminny SonarQube Cloud
Close tab
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Skip to measure filters
Skip to measure filters
Undock sidebar
Continuous Code Quality
Favorite Projects
Favorite Projects
Assigned Issues
Assigned Issues
Explore
Explore
Search
Product news
1
Help
New...
Account
app
Project
Overview
Overview
Analysis
Summary
Summary
Issues
Issues
Architecture
Architecture
Security hotspots
Security hotspots
Reporting
Measures
Measures
Activity
Activity
Policies
Intended architecture
Intended architecture
Project
Pull Requests 109
Pull Requests
109
Branches 12
Branches
12
Code...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
19840
|
848
|
40
|
2026-05-11T13:37:54.544411+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778506674544_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/changes
|
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 54 minutes ago
LakyLak
LakyLak
commented
54 minutes ago
54 minutes 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
1 hour 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":"AXButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.18715277,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.21006945,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.23333333,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.25659722,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.27986112,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"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":"View statusView status","depth":13,"on_screen":false,"role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Loading","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Loading merge status","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 2 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":"AXRadioButton","text":"Conversation","depth":15,"on_screen":false,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Conversation","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Commits (2)","depth":15,"on_screen":false,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Commits","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Checks","depth":15,"on_screen":false,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Checks","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Files changed","depth":15,"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":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"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 54 minutes 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":"54 minutes 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":"54 minutes 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":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"added","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commits","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 hour ago","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
2329569210841171261
|
-2050229289186839936
|
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 [URL_WITH_CREDENTIALS]
Show options
LakyLak commented 54 minutes ago
LakyLak
LakyLak
commented
54 minutes ago
54 minutes 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
1 hour ago...
|
19839
|
NULL
|
NULL
|
NULL
|
|
19993
|
859
|
40
|
2026-05-11T14:16:00.793737+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778508960793_m2.jpg...
|
Slack
|
releases (Channel) - Jiminny Inc - 3 new items - S releases (Channel) - Jiminny Inc - 3 new items - Slack...
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":14,"bounds":{"left":0.5152925,"top":1.0,"width":0.011968086,"height":-0.058260202},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":16,"on_screen":true,"role_description":"text"}]...
|
-7457134496557439989
|
-8120564398931363145
|
visual_change
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
*PronllesEXPLORE:V APPapp > Services > Crm > Hubspot › { Client.php > 9g Client › © parseRetryAfter()class Client extends Baseclient 1mpLements Hubspotclientintertapub lic tunction 1sHubspotRateL1m1t Throwable Se : booly Services123134• Hubspol~OpportunitySynestrategy..** HubspotLastModifiedOpenSyncStra...** HubspotLastModifiedSyncStrategy....R HubspotSingleSyncStrategy.php** HubspotSyncStrategyBase.php*R HubspotWebhookBatchSyncStrateg...Pagination** HubspotPaginationService.php* PaginationConfig.php* PaginationState.phpProspectsearchstrategy137pub L1c• tunction-parseretryArter(Throwable se): •1nc~ Servicelraits# OpportunitySyncTrait.php** SyncCrmEntitiesTrait.phpwsuncrields.rait.ono14 WriteCrmTrait.php• Utils• WebhookBatchSvncCollector.ohoBatchSvncRedisService.ohvI Cllient.oho** ClosedDealStagesService.php* DealFieldsService.oho# DecorateActivity.php• FieldDefinitions.ohn# FieldTypeConverter.php# HubspotClientinterface.phpHubspotTokenManager.php€ DavloadRuilder nhnRemoteCrmObjectManipulator.php«* PecnonceNormalize nhnR Service.php#R SyncFieldAction.php4 SyncRelatedActivityManager.php4 WebhookSyncBatchProcessor.php› IntegrationApp• Listeners> Metadata> MigrationV Pipedrive• OpportunitySvncStrateavProspectSearchStrateav> OUTLINE, TIMELINGPa JY-20725-handle-HS-search-rate-limit* ©1t• method exists se,'getResponseHeaders'•Sheaders =Se->aetResoonseHeaderso-?:-0*svalue = $headers ('Retry-After'] -27 Sheaders ('retry-$value = $value [0] - 27 null;. (15, nuneric(svatue)) (Smessage = strtolower ($e->getMessage()):it• (sur contains(smessage, ' dally y)'1return 600;if• (str_contains(Smessage,'ten secondly")) •{• return - 10:if - (str_contains($message, 'secondly')) €return- 1;•Sthis→>loq→>warningHubspot•No- retrv-after header orget_class (Se),message" .= Smessage.return 10;public function getMinimumApiVersion(): stringreturn self::MIN_API VERSION;public function getInstance(): Factory= Sthis→>accesstoken'oauth?'''base url => Sthis->baseUruoublic function aetNewinstance: Discovervreturn HubSpot\Factorv:.createWithAccessToken/Sthis->ad@6A 9026>0 ld100% 5•••|D+÷cNew Tab@ Screenpipe — ArchiveAll docs - AFFINE4 New Tabl• -2 app.affine.pro/workspace/e90fb5c6-df16-48cd-ab2d-fe7a6cb103bc/allDocs Collections TagsDemo WorkspaceAllSearchMay 8, 2026 - 1E All docsGetting Startedea JournalsWelcome to AFFiNE! You can start with a normal page, with richly formatted text, markdown support, links, and a lot of other blocks.Click anywhere to start typingClick to edit this line, and then drag the handle ..Never Uodated. 1Notifications1* IntelligenceHow to use folder and Tagsove docs into folders (draggina works as well) Docs can belona to multiple foldersExpand into to view and manage tags)ê SettingsSavorites -No favoritedOrganize"• First FolderTaqsCollectionsOthers+i Trash,J, Imporid% Invite membersTemplate(1 Learn more ?3a adoN Download AppMon 11 May 1/.10.00New doc3dagoO t :3dago O# :...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
20248
|
871
|
40
|
2026-05-11T14:48:53.348999+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778510933348_m2.jpg...
|
Code
|
Client.php (Working Tree) (Client.php) — app — 9 p Client.php (Working Tree) (Client.php) — app — 9 problems in this file • Modified...
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧ Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧G)
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update
2
Testing
Claude Code
SOURCE CONTROL
SOURCE CONTROL
Changes Section
CHANGES
CHANGES
Commit Changes on "JY-20725-handle-HS-search-rate-limit"
Commit
More Actions...
Changes
17
.env.local
M
.env.nikilocal
U
.env.other
U
ids.txt
U
raw_sql_query.sql
U
WEBHOOK_FILTERING_IMPLEMENTATION.md
U
JiminnyDebugCommand.php
app/Console/Commands
M
SimulateWebhooksCommand.php
app/Console/Commands/Crm/Hubspot
U
CreateMockAskJiminnyReportResultCommand.php
app/Console/Commands/Reports
U
RateLimitException.php
app/Exceptions
M
MatchActivityCrmData.php
app/Jobs/Crm
M
Client.php
app/Services/Crm/Hubspot
9, M
logging.php
config
M
favicon.ico
public
U
HandleHubspotRateLimitTest.php
tests/Unit/Jobs/Middleware
M
CanAccessAiReportsTest.php
tests/Unit/Policies
U
ClientTest.php
tests/Unit/Services/Crm/Hubspot
M
Graph Section
GRAPH
GRAPH
JY-20725 add more tests
Lukas Kovalik
JY-20725-handle-HS-search-rate-limit
JY-20725 add tests
Lukas Kovalik
JY-20725 add HS rate limit handling on activities rematching
Lukas Kovalik
Merge pull request #12056 from jiminny/JY-20818-move-AJ-reports-to-separated-datadog-metric
Lukas Kovalik
origin/master
Merge branch 'master' into JY-20818-move-AJ-reports-to-separated-datadog-metric
Lukas Kovalik
Merge pull request #12057 from jiminny/JY-20819-increase-download-transctip-rate-limit
mihailmihaylovjiminny
JY-20819: Increase download transcription rate limit
mihail.mihaylov
JY-20818 move ask jiminny reports to its own datadog metric
Lukas Kovalik
Merge pull request #12052 from jiminny/JY-20817-fix-deleting-old-tracks
mihailmihaylovjiminny
Merge branch 'master' into JY-20817-fix-deleting-old-tracks
mihailmihaylovjiminny
Merge pull request #12047 from jiminny/JY-20662-remove-word-boost
ilian-jiminny
JY-20662 return void
ilian
JY-20662 Removed word_boost parameter from Assembly transcription request
ilian
JY-20817: Fix deleting old tracks
mihail.mihaylov
Merge pull request #12043 from jiminny/JY-19938-bot-status-in-csv-es
ilian-jiminny
Merge branch 'master' into JY-19938-bot-status-in-csv-es
ilian-jiminny
Merge pull request #12044 from jiminny/JY-19938-ES-mapping-update
ilian-jiminny
JY-19938 Added consent information and recording error reason to Elastic Search mapping
ilian
JY-19938 reorder array map
ilian
JY-19938: Address PR review comments
ilian
JY-19938 lint fixes
ilian
MatchActivityCrmData.php, Editor Group 1
RateLimitException.php, Editor Group 1
HandleHubspotRateLimit.php, Editor Group 1
Client.php, Editor Group 1
Client.php (Working Tree) (Client.php), preview, Editor Group 1
HubspotPaginationService.php, Editor Group 1
Review rate limit handli…, Editor Group 2
remote
app (Git) - JY-20725-handle-HS-search-rate-limit*, Checkout Branch/Tag...
JY-20725-handle-HS-search-rate-limit*
app (Git) - Synchronize Changes
Errors: 6, Warnings: 10, Infos: 28
6
10
28
Notifications
key, PHP extension: Premium features not active.
8.3, Language Level: 8.3
Sign In
Sign In
PHP
LF
UTF-8
Spaces: 4
Ln 120, Col 1
git-commit Not Committed Yet
Not Committed Yet
Diff editor
Clear
Review rate limit handling for HubSpot job queue
Session history
New session
Message actions
RateLimitException.php#9-9
RateLimitException.php#9-9
Reveiw the diff. Mostly
@app/Jobs/Crm/MatchActivityCrmData.php
,
@app/Exceptions/RateLimitException.php
,
@app/Jobs/Middleware/HandleHubspotRateLimit.php
,
@app/Services/Crm/Hubspot/Client.php
and
@app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php
. The issue is I am trying to make sure that instant spike of MatchActivityCrmData jobs willl handle 429 exceptions from hubspot. Revewi ti carefully and try to see potential issues and bottlenecks. Also RateLimitException was changerd from LogicException to RuntimeException. Is it ok. This exception is used by other paerts of code. Will ti break anything?
Thought for 5s
Thought for 5s
I'll review the implementation carefully. Let me first check how
RateLimitException
is used elsewhere and look at the test files and
PaginationState
.
Bash
Find all usages of RateLimitException outside the changed files
IN
grep -rn "RateLimitException" /Users/lukas/jiminny/app/app --include="*.php" | grep -v "HandleHubspotRateLimit\|MatchActivityCrmData\|Client.php\|RateLimitException.php"...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Explorer (⇧⌘E)","depth":19,"bounds":{"left":0.0,"top":0.047885075,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.057462092,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Search (⇧⌘F)","depth":19,"bounds":{"left":0.0,"top":0.08619314,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.09577015,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Source Control (⌃⇧G)","depth":19,"bounds":{"left":0.0,"top":0.1245012,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":true},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.13407822,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Run and Debug (⇧⌘D)","depth":19,"bounds":{"left":0.0,"top":0.16280925,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.17238627,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Remote Explorer","depth":19,"bounds":{"left":0.0,"top":0.20111732,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.21069433,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Extensions (⇧⌘X) - 2 require update","depth":19,"bounds":{"left":0.0,"top":0.23942538,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.2490024,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":22,"bounds":{"left":0.009640957,"top":0.2601756,"width":0.0019946808,"height":0.008778931},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Testing","depth":19,"bounds":{"left":0.0,"top":0.27773345,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.28731045,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Claude Code","depth":19,"bounds":{"left":0.0,"top":0.3160415,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"SOURCE CONTROL","depth":17,"bounds":{"left":0.022606382,"top":0.047885075,"width":0.034242023,"height":0.02793296},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"SOURCE CONTROL","depth":18,"bounds":{"left":0.022606382,"top":0.056664005,"width":0.034242023,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Changes Section","depth":21,"bounds":{"left":0.015957447,"top":0.07581804,"width":0.09940159,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"","depth":23,"bounds":{"left":0.01662234,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXHeading","text":"CHANGES","depth":22,"bounds":{"left":0.022606382,"top":0.07581804,"width":0.01861702,"height":0.017557861},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"CHANGES","depth":23,"bounds":{"left":0.022606382,"top":0.079010375,"width":0.01861702,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXTextArea","text":"","depth":28,"bounds":{"left":0.024601065,"top":0.09896249,"width":0.07247341,"height":0.015961692},"on_screen":true,"value":"","role_description":"editor","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":29,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Commit Changes on \"JY-20725-handle-HS-search-rate-limit\"","depth":26,"bounds":{"left":0.022273935,"top":0.1245012,"width":0.08045213,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.052526597,"top":0.12849163,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Commit","depth":27,"bounds":{"left":0.058843084,"top":0.1292897,"width":0.014960106,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.059175532,"top":0.1292897,"width":0.0029920214,"height":0.011173184}},{"char_start":1,"char_count":5,"bounds":{"left":0.061835106,"top":0.1292897,"width":0.011968086,"height":0.011173184}}],"role_description":"text"},{"role":"AXPopUpButton","text":"More Actions...","depth":26,"bounds":{"left":0.10305851,"top":0.1245012,"width":0.00831117,"height":0.0207502},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.1043883,"top":0.12849163,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.019614361,"top":0.15163608,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Changes","depth":27,"bounds":{"left":0.025930852,"top":0.15163608,"width":0.01761968,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.025930852,"top":0.15243416,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":6,"bounds":{"left":0.028922873,"top":0.15243416,"width":0.014960106,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"17","depth":27,"bounds":{"left":0.10571808,"top":0.15243416,"width":0.0039893617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.10605053,"top":0.15243416,"width":0.0016622341,"height":0.0103751}},{"char_start":1,"char_count":1,"bounds":{"left":0.10771277,"top":0.15243416,"width":0.0019946808,"height":0.0103751}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.16759777,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".env.local","depth":28,"bounds":{"left":0.028590426,"top":0.16919394,"width":0.01861702,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.16999201,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":9,"bounds":{"left":0.029920213,"top":0.16999201,"width":0.01761968,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":28,"bounds":{"left":0.106715426,"top":0.16999201,"width":0.003656915,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.18515563,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".env.nikilocal","depth":28,"bounds":{"left":0.028590426,"top":0.1867518,"width":0.025598405,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.18754987,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":13,"bounds":{"left":0.029920213,"top":0.18754987,"width":0.024268618,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"U","depth":28,"bounds":{"left":0.107380316,"top":0.18754987,"width":0.0029920214,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.20271349,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".env.other","depth":28,"bounds":{"left":0.028590426,"top":0.20430966,"width":0.019946808,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.20510775,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":9,"bounds":{"left":0.029920213,"top":0.20510775,"width":0.01861702,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"U","depth":28,"bounds":{"left":0.107380316,"top":0.20510775,"width":0.0029920214,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.22027135,"width":0.0076462766,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ids.txt","depth":28,"bounds":{"left":0.028590426,"top":0.22186752,"width":0.012300532,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.22266561,"width":0.0009973404,"height":0.011971269}},{"char_start":1,"char_count":6,"bounds":{"left":0.029587766,"top":0.22266561,"width":0.011635638,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"U","depth":28,"bounds":{"left":0.107380316,"top":0.22266561,"width":0.0029920214,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.23782921,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"raw_sql_query.sql","depth":28,"bounds":{"left":0.028590426,"top":0.23942538,"width":0.035904255,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.24022347,"width":0.0016622341,"height":0.011971269}},{"char_start":1,"char_count":16,"bounds":{"left":0.03025266,"top":0.24022347,"width":0.034242023,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"U","depth":28,"bounds":{"left":0.107380316,"top":0.24022347,"width":0.0029920214,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.25538707,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"WEBHOOK_FILTERING_IMPLEMENTATION.md","depth":28,"bounds":{"left":0.028590426,"top":0.25698325,"width":0.076130316,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.25778133,"width":0.0043218085,"height":0.011971269}},{"char_start":1,"char_count":34,"bounds":{"left":0.032912236,"top":0.25778133,"width":0.08909574,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"U","depth":28,"bounds":{"left":0.107380316,"top":0.25778133,"width":0.0029920214,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.27294493,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JiminnyDebugCommand.php","depth":28,"bounds":{"left":0.028590426,"top":0.2745411,"width":0.05817819,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.2753392,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":22,"bounds":{"left":0.030917553,"top":0.2753392,"width":0.055851065,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"app/Console/Commands","depth":28,"bounds":{"left":0.08843085,"top":0.2745411,"width":0.01462766,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.0887633,"top":0.27613726,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":19,"bounds":{"left":0.09075798,"top":0.27613726,"width":0.043218084,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":28,"bounds":{"left":0.106715426,"top":0.2753392,"width":0.003656915,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.2905028,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SimulateWebhooksCommand.php","depth":28,"bounds":{"left":0.028590426,"top":0.29209897,"width":0.06781915,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.29289705,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":26,"bounds":{"left":0.03125,"top":0.29289705,"width":0.065159574,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"app/Console/Commands/Crm/Hubspot","depth":28,"bounds":{"left":0.098071806,"top":0.29209897,"width":0.005984043,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.09840426,"top":0.29369512,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":31,"bounds":{"left":0.100398935,"top":0.29369512,"width":0.06881649,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"U","depth":28,"bounds":{"left":0.107380316,"top":0.29289705,"width":0.0029920214,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.30806065,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"CreateMockAskJiminnyReportResultCommand.php","depth":28,"bounds":{"left":0.028590426,"top":0.30965683,"width":0.07646277,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.3104549,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":42,"bounds":{"left":0.03158245,"top":0.3104549,"width":0.099734046,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"app/Console/Commands/Reports","depth":28,"bounds":{"left":0.10538564,"top":0.3104549,"width":0.0003324468,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.13331117,"top":0.31125298,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":27,"bounds":{"left":0.13530585,"top":0.31125298,"width":0.05851064,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"U","depth":28,"bounds":{"left":0.107380316,"top":0.3104549,"width":0.0029920214,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.3256185,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"RateLimitException.php","depth":28,"bounds":{"left":0.028590426,"top":0.3272147,"width":0.047539894,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.32801276,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":21,"bounds":{"left":0.03158245,"top":0.32801276,"width":0.04488032,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"app/Exceptions","depth":28,"bounds":{"left":0.078125,"top":0.3272147,"width":0.024933511,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.078125,"top":0.32881084,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":13,"bounds":{"left":0.08045213,"top":0.32881084,"width":0.026263298,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":28,"bounds":{"left":0.106715426,"top":0.32801276,"width":0.003656915,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.34317636,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchActivityCrmData.php","depth":28,"bounds":{"left":0.028590426,"top":0.34477255,"width":0.054521278,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.34557062,"width":0.0039893617,"height":0.011971269}},{"char_start":1,"char_count":23,"bounds":{"left":0.032579787,"top":0.34557062,"width":0.050531916,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"app/Jobs/Crm","depth":28,"bounds":{"left":0.084773935,"top":0.34477255,"width":0.020279255,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.084773935,"top":0.3463687,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":11,"bounds":{"left":0.087101065,"top":0.3463687,"width":0.023603724,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":28,"bounds":{"left":0.106715426,"top":0.34557062,"width":0.003656915,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.36073422,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Client.php","depth":28,"bounds":{"left":0.028590426,"top":0.3623304,"width":0.020611702,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.36312848,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":9,"bounds":{"left":0.03158245,"top":0.36312848,"width":0.01761968,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"app/Services/Crm/Hubspot","depth":28,"bounds":{"left":0.05119681,"top":0.3623304,"width":0.028590426,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.05119681,"top":0.3639266,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":23,"bounds":{"left":0.053523935,"top":0.3639266,"width":0.047539894,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"9, M","depth":28,"bounds":{"left":0.10206117,"top":0.36312848,"width":0.00831117,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.10206117,"top":0.36312848,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.10472074,"top":0.36312848,"width":0.005984043,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.3782921,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"logging.php","depth":28,"bounds":{"left":0.028590426,"top":0.37988827,"width":0.023936171,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.38068634,"width":0.0009973404,"height":0.011971269}},{"char_start":1,"char_count":10,"bounds":{"left":0.029587766,"top":0.38068634,"width":0.022938829,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"config","depth":28,"bounds":{"left":0.05418883,"top":0.38068634,"width":0.011968086,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.054521278,"top":0.38148445,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":5,"bounds":{"left":0.05651596,"top":0.38148445,"width":0.009640957,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":28,"bounds":{"left":0.106715426,"top":0.38068634,"width":0.003656915,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.39584997,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"favicon.ico","depth":28,"bounds":{"left":0.028590426,"top":0.39744613,"width":0.021609042,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.3982442,"width":0.0016622341,"height":0.011971269}},{"char_start":1,"char_count":10,"bounds":{"left":0.03025266,"top":0.3982442,"width":0.020279255,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"public","depth":28,"bounds":{"left":0.05219415,"top":0.3982442,"width":0.011303191,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.05219415,"top":0.3990423,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":5,"bounds":{"left":0.054521278,"top":0.3990423,"width":0.008976064,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"U","depth":28,"bounds":{"left":0.107380316,"top":0.3982442,"width":0.0029920214,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.41340783,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HandleHubspotRateLimitTest.php","depth":28,"bounds":{"left":0.028590426,"top":0.415004,"width":0.06781915,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.41580206,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":29,"bounds":{"left":0.031914894,"top":0.41580206,"width":0.064494684,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"tests/Unit/Jobs/Middleware","depth":28,"bounds":{"left":0.098071806,"top":0.415004,"width":0.004986702,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.098071806,"top":0.41660017,"width":0.0016622341,"height":0.011173184}},{"char_start":1,"char_count":25,"bounds":{"left":0.09940159,"top":0.41660017,"width":0.04886968,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":28,"bounds":{"left":0.106715426,"top":0.41580206,"width":0.003656915,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.4309657,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"CanAccessAiReportsTest.php","depth":28,"bounds":{"left":0.028590426,"top":0.43256184,"width":0.059175532,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.43335995,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":25,"bounds":{"left":0.03158245,"top":0.43335995,"width":0.05618351,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"tests/Unit/Policies","depth":28,"bounds":{"left":0.089428194,"top":0.43256184,"width":0.013962766,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.08976064,"top":0.43415803,"width":0.0013297872,"height":0.011173184}},{"char_start":1,"char_count":18,"bounds":{"left":0.091090426,"top":0.43415803,"width":0.031914894,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"U","depth":28,"bounds":{"left":0.107380316,"top":0.43335995,"width":0.0029920214,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.44852355,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ClientTest.php","depth":28,"bounds":{"left":0.028590426,"top":0.4501197,"width":0.028922873,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.4509178,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":13,"bounds":{"left":0.03158245,"top":0.4509178,"width":0.026263298,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"tests/Unit/Services/Crm/Hubspot","depth":28,"bounds":{"left":0.059507977,"top":0.4501197,"width":0.043882977,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.059507977,"top":0.4517159,"width":0.0016622341,"height":0.011173184}},{"char_start":1,"char_count":30,"bounds":{"left":0.060837764,"top":0.4517159,"width":0.059507977,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":28,"bounds":{"left":0.106715426,"top":0.4509178,"width":0.003656915,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Graph Section","depth":21,"bounds":{"left":0.015957447,"top":0.60015965,"width":0.09940159,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"","depth":23,"bounds":{"left":0.01662234,"top":0.60255384,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXHeading","text":"GRAPH","depth":22,"bounds":{"left":0.022606382,"top":0.60015965,"width":0.013297873,"height":0.017557861},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"GRAPH","depth":23,"bounds":{"left":0.022606382,"top":0.60415006,"width":0.013297873,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-20725 add more tests","depth":28,"bounds":{"left":0.023271276,"top":0.6201117,"width":0.038231384,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.023271276,"top":0.6209098,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":22,"bounds":{"left":0.025930852,"top":0.6209098,"width":0.05086436,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":28,"bounds":{"left":0.061835106,"top":0.6209098,"width":0.0003324468,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.078457445,"top":0.6217079,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":12,"bounds":{"left":0.080784574,"top":0.6217079,"width":0.023271276,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.06382979,"top":0.6201117,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-20725-handle-HS-search-rate-limit","depth":27,"bounds":{"left":0.06948138,"top":0.6209098,"width":0.032579787,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.06948138,"top":0.6209098,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":35,"bounds":{"left":0.07180851,"top":0.6209098,"width":0.071476065,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.10571808,"top":0.6201117,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-20725 add tests","depth":28,"bounds":{"left":0.023271276,"top":0.63766956,"width":0.03956117,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.023271276,"top":0.63846767,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":17,"bounds":{"left":0.025598405,"top":0.63846767,"width":0.03723404,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":28,"bounds":{"left":0.064494684,"top":0.63846767,"width":0.024933511,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.06482713,"top":0.6392658,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":12,"bounds":{"left":0.066821806,"top":0.6392658,"width":0.022938829,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching","depth":28,"bounds":{"left":0.023271276,"top":0.6552275,"width":0.08577128,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.023271276,"top":0.6560255,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":59,"bounds":{"left":0.025598405,"top":0.6560255,"width":0.11968085,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":28,"bounds":{"left":0.109707445,"top":0.6560255,"width":0.0003324468,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.14727394,"top":0.65682364,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":12,"bounds":{"left":0.14926861,"top":0.65682364,"width":0.022938829,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Merge pull request #12056 from jiminny/JY-20818-move-AJ-reports-to-separated-datadog-metric","depth":28,"bounds":{"left":0.026928192,"top":0.67278534,"width":0.049534574,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":28,"bounds":{"left":0.0774601,"top":0.6735834,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.07945479,"top":0.67278534,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"origin/master","depth":27,"bounds":{"left":0.08510638,"top":0.6735834,"width":0.024933511,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Merge branch 'master' into JY-20818-move-AJ-reports-to-separated-datadog-metric","depth":28,"bounds":{"left":0.030585106,"top":0.6903432,"width":0.078457445,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":28,"bounds":{"left":0.109707445,"top":0.69114125,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Merge pull request #12057 from jiminny/JY-20819-increase-download-transctip-rate-limit","depth":28,"bounds":{"left":0.030585106,"top":0.70790106,"width":0.078457445,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"mihailmihaylovjiminny","depth":28,"bounds":{"left":0.109707445,"top":0.7086991,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-20819: Increase download transcription rate limit","depth":28,"bounds":{"left":0.030585106,"top":0.7254589,"width":0.078457445,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"mihail.mihaylov","depth":28,"bounds":{"left":0.109707445,"top":0.72625697,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-20818 move ask jiminny reports to its own datadog metric","depth":28,"bounds":{"left":0.030585106,"top":0.7430168,"width":0.07945479,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":28,"bounds":{"left":0.109707445,"top":0.7438148,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Merge pull request #12052 from jiminny/JY-20817-fix-deleting-old-tracks","depth":28,"bounds":{"left":0.030585106,"top":0.76057464,"width":0.0787899,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"mihailmihaylovjiminny","depth":28,"bounds":{"left":0.109707445,"top":0.7613727,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Merge branch 'master' into JY-20817-fix-deleting-old-tracks","depth":28,"bounds":{"left":0.030585106,"top":0.7781325,"width":0.078125,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"mihailmihaylovjiminny","depth":28,"bounds":{"left":0.109707445,"top":0.77893054,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Merge pull request #12047 from jiminny/JY-20662-remove-word-boost","depth":28,"bounds":{"left":0.030585106,"top":0.79569036,"width":0.0787899,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian-jiminny","depth":28,"bounds":{"left":0.109707445,"top":0.7964884,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-20662 return void","depth":28,"bounds":{"left":0.030585106,"top":0.8132482,"width":0.043218084,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian","depth":28,"bounds":{"left":0.075465426,"top":0.81404626,"width":0.0076462766,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-20662 Removed word_boost parameter from Assembly transcription request","depth":28,"bounds":{"left":0.030585106,"top":0.8308061,"width":0.0787899,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian","depth":28,"bounds":{"left":0.109707445,"top":0.8316041,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-20817: Fix deleting old tracks","depth":28,"bounds":{"left":0.030585106,"top":0.84836394,"width":0.06582447,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"mihail.mihaylov","depth":28,"bounds":{"left":0.098071806,"top":0.84836394,"width":0.010305851,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Merge pull request #12043 from jiminny/JY-19938-bot-status-in-csv-es","depth":28,"bounds":{"left":0.030585106,"top":0.8659218,"width":0.0787899,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian-jiminny","depth":28,"bounds":{"left":0.109707445,"top":0.8667199,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Merge branch 'master' into JY-19938-bot-status-in-csv-es","depth":28,"bounds":{"left":0.030585106,"top":0.88347965,"width":0.0787899,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian-jiminny","depth":28,"bounds":{"left":0.109707445,"top":0.88427776,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Merge pull request #12044 from jiminny/JY-19938-ES-mapping-update","depth":28,"bounds":{"left":0.030585106,"top":0.9010375,"width":0.0787899,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian-jiminny","depth":28,"bounds":{"left":0.109707445,"top":0.9018356,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-19938 Added consent information and recording error reason to Elastic Search mapping","depth":28,"bounds":{"left":0.030585106,"top":0.9185954,"width":0.0787899,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian","depth":28,"bounds":{"left":0.109707445,"top":0.9193935,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-19938 reorder array map","depth":28,"bounds":{"left":0.030585106,"top":0.93615323,"width":0.056848403,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian","depth":28,"bounds":{"left":0.089428194,"top":0.93695134,"width":0.00731383,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-19938: Address PR review comments","depth":28,"bounds":{"left":0.030585106,"top":0.9537111,"width":0.07912234,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian","depth":28,"bounds":{"left":0.109707445,"top":0.9545092,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-19938 lint fixes","depth":28,"bounds":{"left":0.030585106,"top":0.97126895,"width":0.03756649,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian","depth":28,"bounds":{"left":0.06981383,"top":0.97206706,"width":0.0076462766,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"MatchActivityCrmData.php, Editor Group 1","depth":28,"bounds":{"left":0.11569149,"top":0.047885075,"width":0.04089096,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"RateLimitException.php, Editor Group 1","depth":28,"bounds":{"left":0.15658244,"top":0.047885075,"width":0.0731383,"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":"HandleHubspotRateLimit.php, Editor Group 1","depth":28,"bounds":{"left":0.2293883,"top":0.047885075,"width":0.080119684,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Client.php, Editor Group 1","depth":28,"bounds":{"left":0.30917552,"top":0.047885075,"width":0.05119681,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Client.php (Working Tree) (Client.php), preview, Editor Group 1","depth":28,"bounds":{"left":0.3600399,"top":0.047885075,"width":0.08277926,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXRadioButton","text":"HubspotPaginationService.php, Editor Group 1","depth":28,"bounds":{"left":0.4424867,"top":0.047885075,"width":0.042220745,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.12832446,"top":0.07821229,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.15093085,"top":0.07821229,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.16489361,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.1875,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.22074468,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.22606383,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.24401596,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.24933511,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Review rate limit handli…, Editor Group 2","depth":28,"bounds":{"left":0.5578458,"top":0.047885075,"width":0.07014628,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXButton","text":"remote","depth":16,"bounds":{"left":0.0006648936,"top":0.98244214,"width":0.010638298,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"app (Git) - JY-20725-handle-HS-search-rate-limit*, Checkout Branch/Tag...","depth":16,"bounds":{"left":0.012965426,"top":0.98244214,"width":0.084773935,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.013962766,"top":0.9848364,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-20725-handle-HS-search-rate-limit*","depth":17,"bounds":{"left":0.019281914,"top":0.9856345,"width":0.0774601,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"app (Git) - Synchronize Changes","depth":16,"bounds":{"left":0.09740692,"top":0.98244214,"width":0.0076462766,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Errors: 6, Warnings: 10, Infos: 28","depth":16,"bounds":{"left":0.107380316,"top":0.98244214,"width":0.03756649,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.109042555,"top":0.9848364,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"6","depth":17,"bounds":{"left":0.1143617,"top":0.9856345,"width":0.004986702,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.11934841,"top":0.9848364,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"10","depth":17,"bounds":{"left":0.124667555,"top":0.9856345,"width":0.00731383,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.13164894,"top":0.9848364,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"28","depth":17,"bounds":{"left":0.13696809,"top":0.9856345,"width":0.0063164895,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Notifications","depth":16,"bounds":{"left":0.9886968,"top":0.98244214,"width":0.010638298,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"key, PHP extension: Premium features not active.","depth":16,"bounds":{"left":0.9790558,"top":0.98244214,"width":0.008643617,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"8.3, Language Level: 8.3","depth":16,"bounds":{"left":0.9674202,"top":0.98244214,"width":0.009640957,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sign In","depth":16,"bounds":{"left":0.9428192,"top":0.98244214,"width":0.022938829,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.9444814,"top":0.9848364,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sign In","depth":17,"bounds":{"left":0.94980055,"top":0.9856345,"width":0.014295213,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"PHP","depth":16,"bounds":{"left":0.92952126,"top":0.98244214,"width":0.011635638,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"LF","depth":16,"bounds":{"left":0.91988033,"top":0.98244214,"width":0.007978723,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"UTF-8","depth":16,"bounds":{"left":0.90226066,"top":0.98244214,"width":0.015625,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Spaces: 4","depth":16,"bounds":{"left":0.87832445,"top":0.98244214,"width":0.022273935,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Ln 120, Col 1","depth":16,"bounds":{"left":0.84773934,"top":0.98244214,"width":0.028922873,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"git-commit Not Committed Yet","depth":16,"bounds":{"left":0.80019945,"top":0.98244214,"width":0.045545213,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.8018617,"top":0.9848364,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Not Committed Yet","depth":17,"bounds":{"left":0.8071808,"top":0.9856345,"width":0.036901597,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Diff editor","depth":12,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Clear","depth":12,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Review rate limit handling for HubSpot job queue","depth":19,"bounds":{"left":0.56017286,"top":0.08060654,"width":0.099734046,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Session history","depth":19,"bounds":{"left":0.9780585,"top":0.08060654,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"Session history","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New session","depth":19,"bounds":{"left":0.9886968,"top":0.08060654,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"New session","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Message actions","depth":24,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RateLimitException.php#9-9","depth":23,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"RateLimitException.php#9-9","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Reveiw the diff. Mostly","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"@app/Jobs/Crm/MatchActivityCrmData.php","depth":26,"on_screen":false,"help_text":"Open app/Jobs/Crm/MatchActivityCrmData.php","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":",","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"@app/Exceptions/RateLimitException.php","depth":26,"on_screen":false,"help_text":"Open app/Exceptions/RateLimitException.php","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":",","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"@app/Jobs/Middleware/HandleHubspotRateLimit.php","depth":26,"on_screen":false,"help_text":"Open app/Jobs/Middleware/HandleHubspotRateLimit.php","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":",","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"@app/Services/Crm/Hubspot/Client.php","depth":26,"on_screen":false,"help_text":"Open app/Services/Crm/Hubspot/Client.php","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"and","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"@app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php","depth":26,"on_screen":false,"help_text":"Open app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":". The issue is I am trying to make sure that instant spike of MatchActivityCrmData jobs willl handle 429 exceptions from hubspot. Revewi ti carefully and try to see potential issues and bottlenecks. Also RateLimitException was changerd from LogicException to RuntimeException. Is it ok. This exception is used by other paerts of code. Will ti break anything?","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Thought for 5s","depth":23,"on_screen":false,"role_description":"disclosure triangle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Thought for 5s","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"I'll review the implementation carefully. Let me first check how","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RateLimitException","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"is used elsewhere and look at the test files and","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PaginationState","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Find all usages of RateLimitException outside the changed files","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"grep -rn \"RateLimitException\" /Users/lukas/jiminny/app/app --include=\"*.php\" | grep -v \"HandleHubspotRateLimit\\|MatchActivityCrmData\\|Client.php\\|RateLimitException.php\"","depth":25,"on_screen":false,"role_description":"text"}]...
|
2470456682713394953
|
5357471341080159013
|
visual_change
|
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
Testing
Claude Code
SOURCE CONTROL
SOURCE CONTROL
Changes Section
CHANGES
CHANGES
Commit Changes on "JY-20725-handle-HS-search-rate-limit"
Commit
More Actions...
Changes
17
.env.local
M
.env.nikilocal
U
.env.other
U
ids.txt
U
raw_sql_query.sql
U
WEBHOOK_FILTERING_IMPLEMENTATION.md
U
JiminnyDebugCommand.php
app/Console/Commands
M
SimulateWebhooksCommand.php
app/Console/Commands/Crm/Hubspot
U
CreateMockAskJiminnyReportResultCommand.php
app/Console/Commands/Reports
U
RateLimitException.php
app/Exceptions
M
MatchActivityCrmData.php
app/Jobs/Crm
M
Client.php
app/Services/Crm/Hubspot
9, M
logging.php
config
M
favicon.ico
public
U
HandleHubspotRateLimitTest.php
tests/Unit/Jobs/Middleware
M
CanAccessAiReportsTest.php
tests/Unit/Policies
U
ClientTest.php
tests/Unit/Services/Crm/Hubspot
M
Graph Section
GRAPH
GRAPH
JY-20725 add more tests
Lukas Kovalik
JY-20725-handle-HS-search-rate-limit
JY-20725 add tests
Lukas Kovalik
JY-20725 add HS rate limit handling on activities rematching
Lukas Kovalik
Merge pull request #12056 from jiminny/JY-20818-move-AJ-reports-to-separated-datadog-metric
Lukas Kovalik
origin/master
Merge branch 'master' into JY-20818-move-AJ-reports-to-separated-datadog-metric
Lukas Kovalik
Merge pull request #12057 from jiminny/JY-20819-increase-download-transctip-rate-limit
mihailmihaylovjiminny
JY-20819: Increase download transcription rate limit
mihail.mihaylov
JY-20818 move ask jiminny reports to its own datadog metric
Lukas Kovalik
Merge pull request #12052 from jiminny/JY-20817-fix-deleting-old-tracks
mihailmihaylovjiminny
Merge branch 'master' into JY-20817-fix-deleting-old-tracks
mihailmihaylovjiminny
Merge pull request #12047 from jiminny/JY-20662-remove-word-boost
ilian-jiminny
JY-20662 return void
ilian
JY-20662 Removed word_boost parameter from Assembly transcription request
ilian
JY-20817: Fix deleting old tracks
mihail.mihaylov
Merge pull request #12043 from jiminny/JY-19938-bot-status-in-csv-es
ilian-jiminny
Merge branch 'master' into JY-19938-bot-status-in-csv-es
ilian-jiminny
Merge pull request #12044 from jiminny/JY-19938-ES-mapping-update
ilian-jiminny
JY-19938 Added consent information and recording error reason to Elastic Search mapping
ilian
JY-19938 reorder array map
ilian
JY-19938: Address PR review comments
ilian
JY-19938 lint fixes
ilian
MatchActivityCrmData.php, Editor Group 1
RateLimitException.php, Editor Group 1
HandleHubspotRateLimit.php, Editor Group 1
Client.php, Editor Group 1
Client.php (Working Tree) (Client.php), preview, Editor Group 1
HubspotPaginationService.php, Editor Group 1
Review rate limit handli…, Editor Group 2
remote
app (Git) - JY-20725-handle-HS-search-rate-limit*, Checkout Branch/Tag...
JY-20725-handle-HS-search-rate-limit*
app (Git) - Synchronize Changes
Errors: 6, Warnings: 10, Infos: 28
6
10
28
Notifications
key, PHP extension: Premium features not active.
8.3, Language Level: 8.3
Sign In
Sign In
PHP
LF
UTF-8
Spaces: 4
Ln 120, Col 1
git-commit Not Committed Yet
Not Committed Yet
Diff editor
Clear
Review rate limit handling for HubSpot job queue
Session history
New session
Message actions
RateLimitException.php#9-9
RateLimitException.php#9-9
Reveiw the diff. Mostly
@app/Jobs/Crm/MatchActivityCrmData.php
,
@app/Exceptions/RateLimitException.php
,
@app/Jobs/Middleware/HandleHubspotRateLimit.php
,
@app/Services/Crm/Hubspot/Client.php
and
@app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php
. The issue is I am trying to make sure that instant spike of MatchActivityCrmData jobs willl handle 429 exceptions from hubspot. Revewi ti carefully and try to see potential issues and bottlenecks. Also RateLimitException was changerd from LogicException to RuntimeException. Is it ok. This exception is used by other paerts of code. Will ti break anything?
Thought for 5s
Thought for 5s
I'll review the implementation carefully. Let me first check how
RateLimitException
is used elsewhere and look at the test files and
PaginationState
.
Bash
Find all usages of RateLimitException outside the changed files
IN
grep -rn "RateLimitException" /Users/lukas/jiminny/app/app --include="*.php" | grep -v "HandleHubspotRateLimit\|MatchActivityCrmData\|Client.php\|RateLimitException.php"...
|
20247
|
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/ /Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Client.php...
|
NULL
|
NULL
|
|
20742
|
901
|
40
|
2026-05-11T16:14:53.283503+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778516093283_m2.jpg...
|
Claude
|
Claude
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Skip to content
Skip to content
Click to collapse
Skip to content
Skip to content
Click to collapse
⌘B
Drag to resize
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/%'
to slice by feature area....
|
[{"role":"AXLink","text":& [{"role":"AXLink","text":"Skip to content","depth":14,"bounds":{"left":0.0023271276,"top":0.025538707,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Skip to content","depth":15,"bounds":{"left":0.0023271276,"top":0.026336791,"width":0.030917553,"height":0.013567438},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.0023271276,"top":0.027134877,"width":0.0026595744,"height":0.012769354}},{"char_start":1,"char_count":14,"bounds":{"left":0.004986702,"top":0.027134877,"width":0.02825798,"height":0.012769354}}],"role_description":"text"},{"role":"AXStaticText","text":"Click to collapse","depth":16,"bounds":{"left":0.10239362,"top":0.02952913,"width":0.030585106,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.10239362,"top":0.02952913,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":16,"bounds":{"left":0.10538564,"top":0.02952913,"width":0.027925532,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"⌘B","depth":16,"bounds":{"left":0.1349734,"top":0.02952913,"width":0.0063164895,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Drag to resize","depth":16,"bounds":{"left":0.10239362,"top":0.0415004,"width":0.025930852,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.10239362,"top":0.0415004,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":13,"bounds":{"left":0.10538564,"top":0.0415004,"width":0.022938829,"height":0.011971269}}],"role_description":"text"},{"role":"AXButton","text":"Collapse sidebar","depth":15,"bounds":{"left":0.030585106,"top":0.02952913,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search","depth":15,"bounds":{"left":0.03856383,"top":0.02952913,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Chat","depth":16,"bounds":{"left":0.005984043,"top":0.06304868,"width":0.026263298,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cowork","depth":16,"bounds":{"left":0.032579787,"top":0.06304868,"width":0.031914894,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code","depth":16,"bounds":{"left":0.065159574,"top":0.06304868,"width":0.027260639,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New chat ⌘N","depth":15,"bounds":{"left":0.005319149,"top":0.096568234,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"New chat","depth":16,"bounds":{"left":0.015292553,"top":0.09976058,"width":0.019281914,"height":0.013567438},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.015292553,"top":0.10055866,"width":0.0033244682,"height":0.013567438}},{"char_start":1,"char_count":7,"bounds":{"left":0.01861702,"top":0.10055866,"width":0.015957447,"height":0.013567438}}],"role_description":"text"},{"role":"AXStaticText","text":"⌘N","depth":17,"bounds":{"left":0.084109046,"top":0.10055866,"width":0.006981383,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Projects","depth":15,"bounds":{"left":0.005319149,"top":0.11731844,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Artifacts","depth":15,"bounds":{"left":0.005319149,"top":0.13806863,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Customize","depth":15,"bounds":{"left":0.005319149,"top":0.15881884,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Pinned","depth":16,"bounds":{"left":0.00731383,"top":0.19872306,"width":0.08510638,"height":0.012769354},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"Bulgarian citizenship application process for EU residents","depth":18,"bounds":{"left":0.005319149,"top":0.21548285,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Bulgarian citizenship application process for EU residents","depth":19,"bounds":{"left":0.08577128,"top":0.21867518,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Dawarich location tracking project","depth":18,"bounds":{"left":0.005319149,"top":0.23703113,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Dawarich location tracking project","depth":19,"bounds":{"left":0.08577128,"top":0.24022347,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Recents","depth":16,"bounds":{"left":0.00731383,"top":0.26735833,"width":0.064494684,"height":0.012769354},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"View all","depth":16,"bounds":{"left":0.0731383,"top":0.26735833,"width":0.019281914,"height":0.012769354},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hubspot BadRequest headers debugging","depth":18,"bounds":{"left":0.005319149,"top":0.28411812,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Hubspot BadRequest headers debugging","depth":19,"bounds":{"left":0.08577128,"top":0.28731045,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Screenpipe sync script failing after recent migrations","depth":18,"bounds":{"left":0.005319149,"top":0.3056664,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Screenpipe sync script failing after recent migrations","depth":19,"bounds":{"left":0.08577128,"top":0.30885875,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Monthly expense tracking","depth":18,"bounds":{"left":0.005319149,"top":0.3272147,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Monthly expense tracking","depth":19,"bounds":{"left":0.08577128,"top":0.33040702,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Exporting transaction data from Notion to finance hub","depth":18,"bounds":{"left":0.005319149,"top":0.34876296,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Exporting transaction data from Notion to finance hub","depth":19,"bounds":{"left":0.08577128,"top":0.3519553,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"💬 How much have I spent for groc…","depth":18,"bounds":{"left":0.005319149,"top":0.37031126,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for 💬 How much have I spent for groc…","depth":19,"bounds":{"left":0.08577128,"top":0.3735036,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"April 2026 spending by category","depth":18,"bounds":{"left":0.005319149,"top":0.39185953,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for April 2026 spending by category","depth":19,"bounds":{"left":0.08577128,"top":0.39505187,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code diff review","depth":18,"bounds":{"left":0.005319149,"top":0.41340783,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Code diff review","depth":19,"bounds":{"left":0.08577128,"top":0.41660017,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"HubSpot rate limit implementation strategy","depth":18,"bounds":{"left":0.005319149,"top":0.4349561,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for HubSpot rate limit implementation strategy","depth":19,"bounds":{"left":0.08577128,"top":0.43814844,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Screenpipe retention policy code location","depth":18,"bounds":{"left":0.005319149,"top":0.45650437,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Screenpipe retention policy code location","depth":19,"bounds":{"left":0.08577128,"top":0.45969674,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Viewing retention policy in screenpipe","depth":18,"bounds":{"left":0.005319149,"top":0.47805268,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Viewing retention policy in screenpipe","depth":19,"bounds":{"left":0.08577128,"top":0.481245,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Clean shot x video recording termination issue","depth":18,"bounds":{"left":0.005319149,"top":0.49960095,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Clean shot x video recording termination issue","depth":19,"bounds":{"left":0.08577128,"top":0.5027933,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"HubSpot rate limit handling with executeRequest","depth":18,"bounds":{"left":0.005319149,"top":0.5211492,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for HubSpot rate limit handling with executeRequest","depth":19,"bounds":{"left":0.08577128,"top":0.5243416,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Untitled","depth":18,"bounds":{"left":0.005319149,"top":0.54269755,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options","depth":19,"bounds":{"left":0.08577128,"top":0.54588985,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"💬 Screen pipe. Is there ability…","depth":18,"bounds":{"left":0.005319149,"top":0.5642458,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for 💬 Screen pipe. Is there ability…","depth":19,"bounds":{"left":0.08577128,"top":0.5674381,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"SMB mount access inconsistency between Finder and iTerm","depth":18,"bounds":{"left":0.005319149,"top":0.5857941,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for SMB mount access inconsistency between Finder and iTerm","depth":19,"bounds":{"left":0.08577128,"top":0.58898646,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"💬 What is the best switch I can…","depth":18,"bounds":{"left":0.005319149,"top":0.60734236,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for 💬 What is the best switch I can…","depth":19,"bounds":{"left":0.08577128,"top":0.6105347,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Permission denied on screenpipe volume","depth":18,"bounds":{"left":0.005319149,"top":0.62889063,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Permission denied on screenpipe volume","depth":19,"bounds":{"left":0.08577128,"top":0.632083,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Screenpipe sync database attachment error","depth":18,"bounds":{"left":0.005319149,"top":0.65043896,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Screenpipe sync database attachment error","depth":19,"bounds":{"left":0.08577128,"top":0.65363127,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Last swimming outing with Dani","depth":18,"bounds":{"left":0.005319149,"top":0.67198724,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Last swimming outing with Dani","depth":19,"bounds":{"left":0.08577128,"top":0.67517954,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Definition of incarcerated","depth":18,"bounds":{"left":0.005319149,"top":0.6935355,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Definition of incarcerated","depth":19,"bounds":{"left":0.08577128,"top":0.6967279,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Lukas Pro","depth":15,"bounds":{"left":0.005319149,"top":0.9696728,"width":0.038231384,"height":0.01915403},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Get apps and extensions","depth":15,"bounds":{"left":0.08510638,"top":0.9696728,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Screenpipe sync script failing after recent migrations, rename chat","depth":19,"bounds":{"left":0.10239362,"top":0.02793296,"width":0.119015954,"height":0.022346368},"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,"bounds":{"left":0.10372341,"top":0.031923383,"width":0.11635638,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.10372341,"top":0.031923383,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":53,"bounds":{"left":0.106715426,"top":0.031923383,"width":0.113696806,"height":0.014365523}}],"role_description":"text"},{"role":"AXPopUpButton","text":"More options for Screenpipe sync script failing after recent migrations","depth":19,"bounds":{"left":0.22174202,"top":0.02793296,"width":0.006981383,"height":0.022346368},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open sidebar","depth":21,"bounds":{"left":0.47340426,"top":0.026336791,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Share chat","depth":21,"bounds":{"left":0.48537233,"top":0.026336791,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Claude finished the response","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"You said: 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"},{"role":"AXStaticText","text":"to slice by feature area.","depth":26,"on_screen":false,"role_description":"text"}]...
|
-4662598886710169881
|
7363349629560800274
|
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/%'
to slice by feature area....
|
20740
|
NULL
|
NULL
|
NULL
|
|
20812
|
903
|
40
|
2026-05-11T16:19:16.829085+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778516356829_m2.jpg...
|
Claude
|
Claude
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Skip to content
Skip to content
Click to collapse
Skip to content
Skip to content
Click to collapse
⌘B
Drag to resize
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...
|
[{"role":"AXLink","text":& [{"role":"AXLink","text":"Skip to content","depth":14,"bounds":{"left":0.0023271276,"top":0.025538707,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Skip to content","depth":15,"bounds":{"left":0.0023271276,"top":0.026336791,"width":0.030917553,"height":0.013567438},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.0023271276,"top":0.027134877,"width":0.0026595744,"height":0.012769354}},{"char_start":1,"char_count":14,"bounds":{"left":0.004986702,"top":0.027134877,"width":0.02825798,"height":0.012769354}}],"role_description":"text"},{"role":"AXStaticText","text":"Click to collapse","depth":16,"bounds":{"left":0.10239362,"top":0.02952913,"width":0.030585106,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.10239362,"top":0.02952913,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":16,"bounds":{"left":0.10538564,"top":0.02952913,"width":0.027925532,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"⌘B","depth":16,"bounds":{"left":0.1349734,"top":0.02952913,"width":0.0063164895,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Drag to resize","depth":16,"bounds":{"left":0.10239362,"top":0.0415004,"width":0.025930852,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.10239362,"top":0.0415004,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":13,"bounds":{"left":0.10538564,"top":0.0415004,"width":0.022938829,"height":0.011971269}}],"role_description":"text"},{"role":"AXButton","text":"Collapse sidebar","depth":15,"bounds":{"left":0.030585106,"top":0.02952913,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search","depth":15,"bounds":{"left":0.03856383,"top":0.02952913,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Chat","depth":16,"bounds":{"left":0.005984043,"top":0.06304868,"width":0.026263298,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cowork","depth":16,"bounds":{"left":0.032579787,"top":0.06304868,"width":0.031914894,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code","depth":16,"bounds":{"left":0.065159574,"top":0.06304868,"width":0.027260639,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New chat ⌘N","depth":15,"bounds":{"left":0.005319149,"top":0.096568234,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"New chat","depth":16,"bounds":{"left":0.015292553,"top":0.09976058,"width":0.019281914,"height":0.013567438},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.015292553,"top":0.10055866,"width":0.0033244682,"height":0.013567438}},{"char_start":1,"char_count":7,"bounds":{"left":0.01861702,"top":0.10055866,"width":0.015957447,"height":0.013567438}}],"role_description":"text"},{"role":"AXStaticText","text":"⌘N","depth":17,"bounds":{"left":0.084109046,"top":0.10055866,"width":0.006981383,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Projects","depth":15,"bounds":{"left":0.005319149,"top":0.11731844,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Artifacts","depth":15,"bounds":{"left":0.005319149,"top":0.13806863,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Customize","depth":15,"bounds":{"left":0.005319149,"top":0.15881884,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Pinned","depth":16,"bounds":{"left":0.00731383,"top":0.19872306,"width":0.08510638,"height":0.012769354},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"Bulgarian citizenship application process for EU residents","depth":18,"bounds":{"left":0.005319149,"top":0.21548285,"width":0.087765954,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Bulgarian citizenship application process for EU residents","depth":19,"bounds":{"left":0.08577128,"top":0.21867518,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-5221351508805849111
|
6777821198880100109
|
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
VIeWWindowmeltScreenpipe sync script failing after recent migrations0, Chat:= Cowork+ New chatã Projectso0 Arutacts₴ CustomizeBu garian cit zenshio apolication proces:Dawarich location tracking projectHubspot Badkequest headers debuggin.Screenpipe sunc script tailing after receiMonthly expense trackingEynorting transaction data from Notion® How much have I spent for groc...Code dift reviewHubSpot rate limit imolementation strateScreenpipe retention policy code locatioViewing retention policy in screenpipeclean snot x video recoraing terminaticHubSpot rate limit handling with executeUntitledaScreen oine. Is there ability.SMB mount access inconsistency betweWhat is the best switch I can..Last swimming outing with DaniDefinition of incarceratedbut how would that work with frames.id = 1 and all data there frame_id isforeign key? If I reinstall the frames-id will start from 1 again.Resolved referential integrity through composite key joins using machine id ›xacuv the right question to ask. Here's now it WorksThe foreign key isn't elements. frame_id → frames.id anymore. It's(elements.machine_id, elements.frame_id) (frames.machine_id, frames.id).The machine id is part of the lookup. not iust sitting alongside it. Let me walk through alconcrete example.Before reinstallSource frames (machine_id = A):id=1, timestamp=2026-04-14, app="PhpStorm"source elementsid=1, frame_id=1, text="hello"id=2, frame_id=1,texte"worldtSync script does this - note the JOIN to fetch machine_id at insert time:INSERT INTO nas.elements (id, machine_id, frame_id, text, ...)SELtCl e.1d, T.machine 1d, e.trame 1d. e.text. ...FROM main.elements eJoIN main. frames + ON e.frame 1d = f.1dWHERE date(f.timestamp) = '2026-04-14';So the NAS rows look like:plements.(machine_id=A, id=1, frame_id=1, "hello")(machine id=A. id=2. frame id=1. "world")framesmachine id=A. id=1. 2026-04-14)Write a message…Opus 4.7 AdaptivelK Lukas. ProClaude is Al and can make mistakes. Please double-check responses., 50 lal100% C28• Mon 11 May 19:19:16→CNew Tab(Screenpipe - ArchiveAll docs - AFFINEam) DXP4800PLUS-B5F8* New Tab@ Screenpipe - Archive@ SQLite Web: archive.db x(*SQLite Web: db.sqlite+ New Tab• db.screenpipe.lakylak.xyz/frames/content/sqlite-web 0.7.2archive.db frames 96749 rows, showing page 1eletlielllselements fts (v)elements_fts_configelements_fts_dataelements_fts_idxframesframes_fts (v)frames_fts_configframes_fts_dataframes_fts_idxmeetingsocr_textui_eventsui_events_fts (v)ui_events_fts_configui_events_fts_dataui_events_fts_idxvideo_chunksToggle helper tablesstructureContentQuervExportvideo_chunk_id offset_index timestampname8037 1522026-04-14T06:23:20.487451+00:00Users/lukas/.screenpipe/data/data/2026-04-14/1776app name window name Tocused browser url NULLSlack2026-04-14T06:23:20.994555÷00:00 /Users/Slacklukas/.screenpipe/data/2026-04-14/17762026-04-14T06:23:23.730853+00:00/Users/ukas/.screenpineldataldata/2026-04-14/17762026-04-14T06:23:24.310310+00:00/Users)data/datal2026-04-14/177612026-04-14T06:23:25.864393+00:00 /Users/lukas/.screenpipe/data/data/2026-04-14/1776NULL2026-04-14T06:23:25.848448+00:00 /Users/lukas/.screenpipe/dataldata/2026-04-14/1776Slack2026-04-14T06:23:27.230179÷00:00/Users/lukas/.screenpipe/data/2026-04-14/1776NULL2026-04-14T06:23:30.287923+00:00/Users/lukas/.screenoioeldatoldata/2026-04-14/1776NULL?aleam92229ezoneananlearellNULUlukas/.screenpipe/data/datal2026-04-14/177612026-04-14706:23:56.387802÷00:00 | /Users/NULLlukas/.screenpipe/data/data/2026-04-14/1776Jiminny Inc-Slack(Channel) -Jiminny Inc -SlackNULLNULLNULLIToast (DM) -Jiminny Inc -SlackNULLNULLNULLINULINULLNULLNULLNULLNULLNULLNULLNULLdevicemonitomonitomonitomonitomonitomonitomonitcmonitomonitomonito...
|
20809
|
NULL
|
NULL
|
NULL
|
|
21151
|
923
|
40
|
2026-05-11T17:15:30.749068+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778519730749_m2.jpg...
|
iTerm2
|
-zsh
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Last login: Sun May 10 21:10:26 on ttys013
Poetry Last login: Sun May 10 21:10:26 on ttys013
Poetry could not find a pyproject.toml file in /Users/lukas or its parents
Poetry could not find a pyproject.toml file in /Users/lukas or its parents
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ cat ~/.screenpipe/screenpipe_sync.sh | pbcopy
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ op
DOCKER
Close Tab
DEV (docker)
Close Tab
APP (-zsh)
Close Tab
-zsh
Close Tab
-zsh
Close Tab
screenpipe"
Close Tab
-zsh
Close Tab
⌥⌘1
-zsh...
|
[{"role":"AXTextArea","text [{"role":"AXTextArea","text":"Last login: Sun May 10 21:10:26 on ttys013\n\nPoetry could not find a pyproject.toml file in /Users/lukas or its parents\n\nPoetry could not find a pyproject.toml file in /Users/lukas or its parents\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ cat ~/.screenpipe/screenpipe_sync.sh | pbcopy\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ op","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.4787234,"height":-0.06304872},"on_screen":true,"value":"Last login: Sun May 10 21:10:26 on ttys013\n\nPoetry could not find a pyproject.toml file in /Users/lukas or its parents\n\nPoetry could not find a pyproject.toml file in /Users/lukas or its parents\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ cat ~/.screenpipe/screenpipe_sync.sh | pbcopy\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ op","is_focused":true},{"role":"AXRadioButton","text":"DOCKER","depth":2,"bounds":{"left":0.27027926,"top":1.0,"width":0.06732048,"height":-0.042298436},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.27227393,"top":1.0,"width":0.005319149,"height":-0.04549086},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"DEV (docker)","depth":2,"bounds":{"left":0.33759972,"top":1.0,"width":0.06732048,"height":-0.042298436},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.33959442,"top":1.0,"width":0.005319149,"height":-0.04549086},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"APP (-zsh)","depth":2,"bounds":{"left":0.40492022,"top":1.0,"width":0.06732048,"height":-0.042298436},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.4069149,"top":1.0,"width":0.005319149,"height":-0.04549086},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.4722407,"top":1.0,"width":0.06732048,"height":-0.042298436},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.4742354,"top":1.0,"width":0.005319149,"height":-0.04549086},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.53956115,"top":1.0,"width":0.06715426,"height":-0.042298436},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.5415558,"top":1.0,"width":0.005319149,"height":-0.04549086},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"screenpipe\"","depth":2,"bounds":{"left":0.60671544,"top":1.0,"width":0.06715426,"height":-0.042298436},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.6087101,"top":1.0,"width":0.005319149,"height":-0.04549086},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.67386967,"top":1.0,"width":0.06715426,"height":-0.042298436},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.67586434,"top":1.0,"width":0.005319149,"height":-0.04549086},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"⌥⌘1","depth":1,"bounds":{"left":0.7273936,"top":1.0,"width":0.01861702,"height":-0.023144484},"on_screen":true,"automation_id":"_NS:8","role_description":"text"},{"role":"AXStaticText","text":"-zsh","depth":1,"bounds":{"left":0.50398934,"top":1.0,"width":0.010970744,"height":-0.02394259},"on_screen":true,"role_description":"text"}]...
|
-8039392039186840489
|
-4070526003869332479
|
click
|
accessibility
|
NULL
|
Last login: Sun May 10 21:10:26 on ttys013
Poetry Last login: Sun May 10 21:10:26 on ttys013
Poetry could not find a pyproject.toml file in /Users/lukas or its parents
Poetry could not find a pyproject.toml file in /Users/lukas or its parents
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ cat ~/.screenpipe/screenpipe_sync.sh | pbcopy
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ op
DOCKER
Close Tab
DEV (docker)
Close Tab
APP (-zsh)
Close Tab
-zsh
Close Tab
-zsh
Close Tab
screenpipe"
Close Tab
-zsh
Close Tab
⌥⌘1
-zsh...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
21439
|
937
|
40
|
2026-05-11T17:51:05.484160+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778521865484_m2.jpg...
|
Code
|
screenpipe_sync.sh — screenpipe [SSH: nas]
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧ Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧G) - 10 pending changes
10
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update
2
Claude Code
Containers
EXPLORER
EXPLORER
Explorer Section: screenpipe [SSH: nas]
Explorer Section: screenpipe [SSH: nas]
SCREENPIPE [SSH: NAS]...
|
[{"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) - 10 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":"10","depth":22,"bounds":{"left":0.00831117,"top":0.1452514,"width":0.003656915,"height":0.008778931},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.00831117,"top":0.14604948,"width":0.0016622341,"height":0.007980846}},{"char_start":1,"char_count":1,"bounds":{"left":0.009973404,"top":0.14604948,"width":0.0023271276,"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":"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: screenpipe [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: screenpipe [SSH: nas]","depth":22,"bounds":{"left":0.022606382,"top":0.07581804,"width":0.045877658,"height":0.017557861},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"SCREENPIPE [SSH: NAS]","depth":23,"bounds":{"left":0.022606382,"top":0.079010375,"width":0.045877658,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.022606382,"top":0.07980846,"width":0.0026595744,"height":0.0103751}},{"char_start":1,"char_count":20,"bounds":{"left":0.025265958,"top":0.07980846,"width":0.043218084,"height":0.0103751}}],"role_description":"text"}]...
|
5994293629059135298
|
-5588377913675529848
|
click
|
accessibility
|
NULL
|
Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧ Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧G) - 10 pending changes
10
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update
2
Claude Code
Containers
EXPLORER
EXPLORER
Explorer Section: screenpipe [SSH: nas]
Explorer Section: screenpipe [SSH: nas]
SCREENPIPE [SSH: NAS]...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
21577
|
943
|
40
|
2026-05-11T18:06:31.258999+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778522791258_m2.jpg...
|
Firefox
|
SQLite Web: db.sqlite — Personal
|
True
|
sqlite.screenpipe.lakylak.xyz/audio_tags/content/
|
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
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
sqlite-web 0.7.2
sqlite-web 0.7.2
db.sqlite
db.sqlite
audio_tags
0 rows, showing page 1
Query
Query
table name...
_sqlx_migrations
_sqlx_migrations
audio_chunks
audio_chunks
audio_tags
audio_tags
audio_transcriptions
audio_transcriptions
audio_transcriptions_fts (v)
audio_transcriptions_fts
(v)
audio_transcriptions_...
audio_transcriptions_...
audio_transcriptions_...
audio_transcriptions_...
audio_transcriptions_...
audio_transcriptions_...
elements
elements
elements_fts (v)
elements_fts
(v)
elements_fts_config
elements_fts_config
elements_fts_data
elements_fts_data
elements_fts_idx
elements_fts_idx
frames
frames
frames_fts (v)
frames_fts
(v)
frames_fts_config
frames_fts_config
frames_fts_data
frames_fts_data
frames_fts_idx
frames_fts_idx
meetings
meetings
memories
memories
memories_fts (v)
memories_fts
(v)
memories_fts_config
memories_fts_config
memories_fts_data
memories_fts_data
memories_fts_idx
memories_fts_idx
ocr_text
ocr_text
pipe_executions
pipe_executions
pipe_scheduler_state
pipe_scheduler_state
secrets
secrets
speaker_embeddings
speaker_embeddings
speakers
speakers
sqlite_sequence
sqlite_sequence
sqlite_stat1
sqlite_stat1
sqlite_stat4
sqlite_stat4
tags
tags
ui_events
ui_events
ui_events_fts (v)
ui_events_fts
(v)
ui_events_fts_config
ui_events_fts_config
ui_events_fts_data
ui_events_fts_data
ui_events_fts_idx
ui_events_fts_idx
video_chunks
video_chunks
vision_tags
vision_tags
Toggle helper tables
Toggle helper tables
Structure
Structure
Content
Content
Query
Query
Export
Export
audio_chunk_id
audio_chunk_id
tag_id
tag_id
audio_chunk_id
audio_chunk_id
tag_id
tag_id
«
«
‹
‹
Page 1 / 1
›
›
»
»
SQLite database browser
v0.7.2
, powered by
Flask
Flask
and
Peewee
Peewee
. © 2026
Charles Leifer
Charles Leifer
sqlite.screenpipe.lakylak.xyz/audio_tags/content/...
|
[{"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":true},{"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":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.55651593,"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":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.5028258,"top":0.31524342,"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":"AXLink","text":"sqlite-web 0.7.2","depth":7,"bounds":{"left":0.57413566,"top":0.058260176,"width":0.043218084,"height":0.030726258},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"sqlite-web 0.7.2","depth":8,"bounds":{"left":0.57413566,"top":0.06464485,"width":0.043218084,"height":0.017956903},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"db.sqlite","depth":10,"bounds":{"left":0.62267286,"top":0.05865922,"width":0.023936171,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"db.sqlite","depth":11,"bounds":{"left":0.6253325,"top":0.066640064,"width":0.01861702,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"audio_tags","depth":10,"bounds":{"left":0.64660907,"top":0.066640064,"width":0.024102394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0 rows, showing page 1","depth":9,"bounds":{"left":0.67204124,"top":0.06783719,"width":0.045711435,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Query","depth":8,"bounds":{"left":0.97639626,"top":0.061851557,"width":0.018284574,"height":0.023543496},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Query","depth":9,"bounds":{"left":0.9793883,"top":0.06743815,"width":0.012300532,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"table name...","depth":7,"bounds":{"left":0.5738032,"top":0.111332804,"width":0.061835106,"height":0.023942538},"on_screen":true,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"_sqlx_migrations","depth":9,"bounds":{"left":0.5738032,"top":0.13527533,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"_sqlx_migrations","depth":10,"bounds":{"left":0.57712764,"top":0.13926576,"width":0.038896278,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"audio_chunks","depth":9,"bounds":{"left":0.5738032,"top":0.15802075,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"audio_chunks","depth":10,"bounds":{"left":0.57712764,"top":0.16201118,"width":0.031416222,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"audio_tags","depth":9,"bounds":{"left":0.5738032,"top":0.18076617,"width":0.06200133,"height":0.02434158},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"audio_tags","depth":10,"bounds":{"left":0.5774601,"top":0.18555467,"width":0.025099734,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"audio_transcriptions","depth":9,"bounds":{"left":0.5738032,"top":0.20510775,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"audio_transcriptions","depth":10,"bounds":{"left":0.57712764,"top":0.20909816,"width":0.04654255,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"audio_transcriptions_fts (v)","depth":9,"bounds":{"left":0.5738032,"top":0.22785315,"width":0.06200133,"height":0.040702313},"on_screen":true,"help_text":"audio_transcriptions_fts","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"audio_transcriptions_fts","depth":10,"bounds":{"left":0.57712764,"top":0.23184358,"width":0.055352394,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(v)","depth":11,"bounds":{"left":0.57712764,"top":0.2482043,"width":0.004986702,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"audio_transcriptions_...","depth":9,"bounds":{"left":0.5738032,"top":0.26855546,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"audio_transcriptions_fts_config","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"audio_transcriptions_...","depth":10,"bounds":{"left":0.57712764,"top":0.2725459,"width":0.053523935,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"audio_transcriptions_...","depth":9,"bounds":{"left":0.5738032,"top":0.29130086,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"audio_transcriptions_fts_data","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"audio_transcriptions_...","depth":10,"bounds":{"left":0.57712764,"top":0.2952913,"width":0.053523935,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"audio_transcriptions_...","depth":9,"bounds":{"left":0.5738032,"top":0.3140463,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"audio_transcriptions_fts_idx","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"audio_transcriptions_...","depth":10,"bounds":{"left":0.57712764,"top":0.3180367,"width":0.053523935,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"elements","depth":9,"bounds":{"left":0.5738032,"top":0.3367917,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"elements","depth":10,"bounds":{"left":0.57712764,"top":0.34078214,"width":0.020777926,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"elements_fts (v)","depth":9,"bounds":{"left":0.5738032,"top":0.35953712,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"elements_fts","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"elements_fts","depth":10,"bounds":{"left":0.57712764,"top":0.36352754,"width":0.030917553,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(v)","depth":11,"bounds":{"left":0.6080452,"top":0.36193135,"width":0.004986702,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"elements_fts_config","depth":9,"bounds":{"left":0.5738032,"top":0.38228253,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"elements_fts_config","depth":10,"bounds":{"left":0.57712764,"top":0.38627294,"width":0.04637633,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"elements_fts_data","depth":9,"bounds":{"left":0.5738032,"top":0.40502793,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"elements_fts_data","depth":10,"bounds":{"left":0.57712764,"top":0.40901837,"width":0.042220745,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"elements_fts_idx","depth":9,"bounds":{"left":0.5738032,"top":0.42777336,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"elements_fts_idx","depth":10,"bounds":{"left":0.57712764,"top":0.43176377,"width":0.0390625,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"frames","depth":9,"bounds":{"left":0.5738032,"top":0.45051876,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"frames","depth":10,"bounds":{"left":0.57712764,"top":0.45450917,"width":0.015791224,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"frames_fts (v)","depth":9,"bounds":{"left":0.5738032,"top":0.47326416,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"frames_fts","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"frames_fts","depth":10,"bounds":{"left":0.57712764,"top":0.4772546,"width":0.025930852,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(v)","depth":11,"bounds":{"left":0.6030585,"top":0.47565842,"width":0.004986702,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"frames_fts_config","depth":9,"bounds":{"left":0.5738032,"top":0.4960096,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"frames_fts_config","depth":10,"bounds":{"left":0.57712764,"top":0.5,"width":0.04138963,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"frames_fts_data","depth":9,"bounds":{"left":0.5738032,"top":0.51875496,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"frames_fts_data","depth":10,"bounds":{"left":0.57712764,"top":0.52274543,"width":0.03723404,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"frames_fts_idx","depth":9,"bounds":{"left":0.5738032,"top":0.5415004,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"frames_fts_idx","depth":10,"bounds":{"left":0.57712764,"top":0.5454908,"width":0.033909574,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"meetings","depth":9,"bounds":{"left":0.5738032,"top":0.5642458,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"meetings","depth":10,"bounds":{"left":0.57712764,"top":0.56823623,"width":0.020944148,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"memories","depth":9,"bounds":{"left":0.5738032,"top":0.58699125,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"memories","depth":10,"bounds":{"left":0.57712764,"top":0.59098166,"width":0.02244016,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"memories_fts (v)","depth":9,"bounds":{"left":0.5738032,"top":0.6097366,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"memories_fts","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"memories_fts","depth":10,"bounds":{"left":0.57712764,"top":0.61372703,"width":0.032579787,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(v)","depth":11,"bounds":{"left":0.6097075,"top":0.6121309,"width":0.004986702,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"memories_fts_config","depth":9,"bounds":{"left":0.5738032,"top":0.63248205,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"memories_fts_config","depth":10,"bounds":{"left":0.57712764,"top":0.63647246,"width":0.048038565,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"memories_fts_data","depth":9,"bounds":{"left":0.5738032,"top":0.6552275,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"memories_fts_data","depth":10,"bounds":{"left":0.57712764,"top":0.6592179,"width":0.043882977,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"memories_fts_idx","depth":9,"bounds":{"left":0.5738032,"top":0.67797285,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"memories_fts_idx","depth":10,"bounds":{"left":0.57712764,"top":0.68196326,"width":0.04055851,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ocr_text","depth":9,"bounds":{"left":0.5738032,"top":0.7007183,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ocr_text","depth":10,"bounds":{"left":0.57712764,"top":0.7047087,"width":0.018783245,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"pipe_executions","depth":9,"bounds":{"left":0.5738032,"top":0.7234637,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipe_executions","depth":10,"bounds":{"left":0.57712764,"top":0.7274541,"width":0.036901597,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"pipe_scheduler_state","depth":9,"bounds":{"left":0.5738032,"top":0.7462091,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipe_scheduler_state","depth":10,"bounds":{"left":0.57712764,"top":0.7501995,"width":0.049035903,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"secrets","depth":9,"bounds":{"left":0.5738032,"top":0.7689545,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"secrets","depth":10,"bounds":{"left":0.57712764,"top":0.7729449,"width":0.016788565,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"speaker_embeddings","depth":9,"bounds":{"left":0.5738032,"top":0.79169995,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"speaker_embeddings","depth":10,"bounds":{"left":0.57712764,"top":0.79569036,"width":0.04886968,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"speakers","depth":9,"bounds":{"left":0.5738032,"top":0.8144453,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"speakers","depth":10,"bounds":{"left":0.57712764,"top":0.8184357,"width":0.020611702,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"sqlite_sequence","depth":9,"bounds":{"left":0.5738032,"top":0.83719075,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"sqlite_sequence","depth":10,"bounds":{"left":0.57712764,"top":0.84118116,"width":0.03723404,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"sqlite_stat1","depth":9,"bounds":{"left":0.5738032,"top":0.8599362,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"sqlite_stat1","depth":10,"bounds":{"left":0.57712764,"top":0.8639266,"width":0.025930852,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"sqlite_stat4","depth":9,"bounds":{"left":0.5738032,"top":0.88268155,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"sqlite_stat4","depth":10,"bounds":{"left":0.57712764,"top":0.88667196,"width":0.026595745,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"tags","depth":9,"bounds":{"left":0.5738032,"top":0.905427,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"tags","depth":10,"bounds":{"left":0.57712764,"top":0.9094174,"width":0.009973404,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ui_events","depth":9,"bounds":{"left":0.5738032,"top":0.9281724,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ui_events","depth":10,"bounds":{"left":0.57712764,"top":0.9321628,"width":0.021775266,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ui_events_fts (v)","depth":9,"bounds":{"left":0.5738032,"top":0.9509178,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"ui_events_fts","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ui_events_fts","depth":10,"bounds":{"left":0.57712764,"top":0.9549082,"width":0.031914894,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(v)","depth":11,"bounds":{"left":0.6090425,"top":0.95331204,"width":0.0048204786,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ui_events_fts_config","depth":9,"bounds":{"left":0.5738032,"top":0.9736632,"width":0.06200133,"height":0.022745412},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ui_events_fts_config","depth":10,"bounds":{"left":0.57712764,"top":0.9776536,"width":0.04737367,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ui_events_fts_data","depth":9,"bounds":{"left":0.5738032,"top":0.99640864,"width":0.06200133,"height":0.0035913587},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ui_events_fts_data","depth":10,"bounds":{"left":0.57712764,"top":1.0,"width":0.043218084,"height":-0.0003989935},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ui_events_fts_idx","depth":9,"bounds":{"left":0.5738032,"top":1.0,"width":0.06200133,"height":-0.019154072},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ui_events_fts_idx","depth":10,"bounds":{"left":0.57712764,"top":1.0,"width":0.039893616,"height":-0.023144484},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"video_chunks","depth":9,"bounds":{"left":0.5738032,"top":1.0,"width":0.06200133,"height":-0.041899443},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"video_chunks","depth":10,"bounds":{"left":0.57712764,"top":1.0,"width":0.03125,"height":-0.045889854},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"vision_tags","depth":9,"bounds":{"left":0.5738032,"top":1.0,"width":0.06200133,"height":-0.06464481},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"vision_tags","depth":10,"bounds":{"left":0.57712764,"top":1.0,"width":0.025930852,"height":-0.068635225},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Toggle helper tables","depth":8,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Toggle helper tables","depth":9,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Structure","depth":9,"bounds":{"left":0.6456117,"top":0.111332804,"width":0.03274601,"height":0.032322425},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Structure","depth":10,"bounds":{"left":0.6512633,"top":0.12011173,"width":0.02144282,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Content","depth":9,"bounds":{"left":0.6783577,"top":0.111332804,"width":0.029421542,"height":0.032322425},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Content","depth":10,"bounds":{"left":0.6840093,"top":0.12011173,"width":0.018118352,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Query","depth":9,"bounds":{"left":0.7077792,"top":0.111332804,"width":0.025265958,"height":0.032322425},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Query","depth":10,"bounds":{"left":0.7134308,"top":0.12011173,"width":0.013962766,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Export","depth":9,"bounds":{"left":0.7330452,"top":0.111332804,"width":0.026097074,"height":0.032322425},"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.7386968,"top":0.12011173,"width":0.014793883,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"audio_chunk_id","depth":10,"bounds":{"left":0.64727396,"top":0.16280925,"width":0.034574468,"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":"audio_chunk_id","depth":11,"bounds":{"left":0.64727396,"top":0.16280925,"width":0.034574468,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"tag_id","depth":10,"bounds":{"left":0.88763297,"top":0.16280925,"width":0.013962766,"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":"tag_id","depth":11,"bounds":{"left":0.88763297,"top":0.16280925,"width":0.013962766,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"audio_chunk_id","depth":10,"bounds":{"left":0.64727396,"top":0.16280925,"width":0.034574468,"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":"audio_chunk_id","depth":11,"bounds":{"left":0.64727396,"top":0.16280925,"width":0.034574468,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"tag_id","depth":10,"bounds":{"left":0.88763297,"top":0.16280925,"width":0.013962766,"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":"tag_id","depth":11,"bounds":{"left":0.88763297,"top":0.16280925,"width":0.013962766,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"«","depth":10,"bounds":{"left":0.6456117,"top":0.19114126,"width":0.011801862,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"«","depth":11,"bounds":{"left":0.6499335,"top":0.19872306,"width":0.0031582448,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"‹","depth":10,"bounds":{"left":0.6584109,"top":0.19114126,"width":0.010804521,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"‹","depth":11,"bounds":{"left":0.6627327,"top":0.19872306,"width":0.0021609042,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Page 1 / 1","depth":11,"bounds":{"left":0.67453456,"top":0.19872306,"width":0.021110373,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"›","depth":10,"bounds":{"left":0.7009641,"top":0.19114126,"width":0.010804521,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"›","depth":11,"bounds":{"left":0.7052859,"top":0.19872306,"width":0.0021609042,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"»","depth":10,"bounds":{"left":0.71276593,"top":0.19114126,"width":0.011801862,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"»","depth":11,"bounds":{"left":0.71708775,"top":0.19872306,"width":0.0031582448,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SQLite database browser","depth":9,"bounds":{"left":0.6456117,"top":0.25019953,"width":0.05236037,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"v0.7.2","depth":9,"bounds":{"left":0.69797206,"top":0.25019953,"width":0.011801862,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", powered by","depth":9,"bounds":{"left":0.70977396,"top":0.25019953,"width":0.027260639,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Flask","depth":9,"bounds":{"left":0.73703456,"top":0.25019953,"width":0.010638298,"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":"Flask","depth":10,"bounds":{"left":0.73703456,"top":0.25019953,"width":0.010638298,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":9,"bounds":{"left":0.74767286,"top":0.25019953,"width":0.009973404,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Peewee","depth":9,"bounds":{"left":0.75764626,"top":0.25019953,"width":0.015791224,"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":"Peewee","depth":10,"bounds":{"left":0.75764626,"top":0.25019953,"width":0.015791224,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":". © 2026","depth":9,"bounds":{"left":0.7734375,"top":0.25019953,"width":0.019614361,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Charles Leifer","depth":9,"bounds":{"left":0.79305184,"top":0.25019953,"width":0.028091755,"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":"Charles Leifer","depth":10,"bounds":{"left":0.79305184,"top":0.25019953,"width":0.028091755,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"sqlite.screenpipe.lakylak.xyz/audio_tags/content/","depth":5,"bounds":{"left":0.57014626,"top":0.9876297,"width":0.0859375,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
8278978438516833671
|
4561192709358210040
|
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
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
sqlite-web 0.7.2
sqlite-web 0.7.2
db.sqlite
db.sqlite
audio_tags
0 rows, showing page 1
Query
Query
table name...
_sqlx_migrations
_sqlx_migrations
audio_chunks
audio_chunks
audio_tags
audio_tags
audio_transcriptions
audio_transcriptions
audio_transcriptions_fts (v)
audio_transcriptions_fts
(v)
audio_transcriptions_...
audio_transcriptions_...
audio_transcriptions_...
audio_transcriptions_...
audio_transcriptions_...
audio_transcriptions_...
elements
elements
elements_fts (v)
elements_fts
(v)
elements_fts_config
elements_fts_config
elements_fts_data
elements_fts_data
elements_fts_idx
elements_fts_idx
frames
frames
frames_fts (v)
frames_fts
(v)
frames_fts_config
frames_fts_config
frames_fts_data
frames_fts_data
frames_fts_idx
frames_fts_idx
meetings
meetings
memories
memories
memories_fts (v)
memories_fts
(v)
memories_fts_config
memories_fts_config
memories_fts_data
memories_fts_data
memories_fts_idx
memories_fts_idx
ocr_text
ocr_text
pipe_executions
pipe_executions
pipe_scheduler_state
pipe_scheduler_state
secrets
secrets
speaker_embeddings
speaker_embeddings
speakers
speakers
sqlite_sequence
sqlite_sequence
sqlite_stat1
sqlite_stat1
sqlite_stat4
sqlite_stat4
tags
tags
ui_events
ui_events
ui_events_fts (v)
ui_events_fts
(v)
ui_events_fts_config
ui_events_fts_config
ui_events_fts_data
ui_events_fts_data
ui_events_fts_idx
ui_events_fts_idx
video_chunks
video_chunks
vision_tags
vision_tags
Toggle helper tables
Toggle helper tables
Structure
Structure
Content
Content
Query
Query
Export
Export
audio_chunk_id
audio_chunk_id
tag_id
tag_id
audio_chunk_id
audio_chunk_id
tag_id
tag_id
«
«
‹
‹
Page 1 / 1
›
›
»
»
SQLite database browser
v0.7.2
, powered by
Flask
Flask
and
Peewee
Peewee
. © 2026
Charles Leifer
Charles Leifer
sqlite.screenpipe.lakylak.xyz/audio_tags/content/...
|
21576
|
NULL
|
NULL
|
NULL
|
|
21753
|
949
|
40
|
2026-05-11T18:21:12.657211+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778523672657_m2.jpg...
|
Finder
|
.screenpipe
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
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...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Favourites","depth":6,"bounds":{"left":0.5046542,"top":0.061452515,"width":0.06216755,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"jiminny","depth":6,"bounds":{"left":0.51263297,"top":0.08140463,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AirDrop","depth":6,"bounds":{"left":0.51263297,"top":0.103751,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Recents","depth":6,"bounds":{"left":0.51263297,"top":0.12609737,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Applications","depth":6,"bounds":{"left":0.51263297,"top":0.14844373,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Documents","depth":6,"bounds":{"left":0.51263297,"top":0.1707901,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Downloads","depth":6,"bounds":{"left":0.51263297,"top":0.19313647,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"lukas","depth":6,"bounds":{"left":0.51263297,"top":0.21548285,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"iCloud","depth":6,"bounds":{"left":0.5046542,"top":0.2434158,"width":0.06216755,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"iCloud Drive","depth":6,"bounds":{"left":0.51263297,"top":0.26336792,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sync folder","depth":6,"bounds":{"left":0.51263297,"top":0.2857143,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Locations","depth":6,"bounds":{"left":0.5046542,"top":0.31364724,"width":0.06216755,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"DXP4800PLUS-B5F","depth":6,"bounds":{"left":0.51263297,"top":0.33359936,"width":0.043218084,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Eject","depth":6,"bounds":{"left":0.55651593,"top":0.33519554,"width":0.0043218085,"height":0.009577015},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false},{"role":"AXStaticText","text":"Network","depth":6,"bounds":{"left":0.51263297,"top":0.35594574,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Tags","depth":6,"bounds":{"left":0.5046542,"top":0.38387868,"width":0.06216755,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"CRM","depth":6,"bounds":{"left":0.51263297,"top":0.4038308,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Orange","depth":6,"bounds":{"left":0.51263297,"top":0.42617717,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Red","depth":6,"bounds":{"left":0.51263297,"top":0.44852355,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Yellow","depth":6,"bounds":{"left":0.51263297,"top":0.4708699,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Green","depth":6,"bounds":{"left":0.51263297,"top":0.49321628,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Blue","depth":6,"bounds":{"left":0.51263297,"top":0.51556265,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Purple","depth":6,"bounds":{"left":0.51263297,"top":0.53790903,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"All Tags…","depth":6,"bounds":{"left":0.51263297,"top":0.5602554,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Name","depth":7,"bounds":{"left":0.5827792,"top":0.06624102,"width":0.011635638,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Date Modified","depth":7,"bounds":{"left":0.8656915,"top":0.06624102,"width":0.026928192,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Size","depth":7,"role_description":"text"}]...
|
5354954459723429647
|
-1840808680972261412
|
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...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
22050
|
962
|
40
|
2026-05-12T06:46:35.504478+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778568395504_m1.jpg...
|
Firefox
|
[JY-20725] [HubSpot] Optimise CRM rematching on de [JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira — Work...
|
True
|
jiminny.atlassian.net/browse/JY-20725?actionerId=7 jiminny.atlassian.net/browse/JY-20725?actionerId=712020%3Ae67fb6e1-5298-44c2-9101-05d96c6e3768&sourceType=assign...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelp(ollDaily - Platform - now100% <28•Tue 12 May 9:46:34meet.google.com/mie-gawc-dsi?authuser=lukas.kovalik%40jiminny.com04 8:::Nikolay Yankov (Presenting, annotating)ChromeFileViewHistoryProfiesTabWindowHelp1 Sez JinX PrinryCo+ Atihttps://jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedissue=JY-20493© AWS|8 SSH Home | SalesforceDatadogPlatform TeamQ Sear$ Jy-9654 / П JY-20493|READY FISmart Instant Nudge Pre-filteringDescriptionProblem:E Nudge Feature Performance Recommendations | Problem #3: Instant Nudge Dispatch FloodSolution:Nudge Feature Performance Recommendations | Solution 2: Smart Instant Nudge Pre filtering (P1)|Process0rganisationInnediateNudges.Job.php:35-69For every AnalyticsCompletedEvent (one per new activity), the job loads every Activity\Search in the team that has atleast one instant nudge and dispatches ProcessNudgeSearchJob per nudge — without comparing the new activity to thesearch filters.ProcessNudgeSearchJob (ProcessNudgeSearchJob.php:42-98 ) then runs an ES onDenandSeroll plus a DB dedup chunk loop(NudgeRunFactory.php:195-225). When 0 new activities are found it bails on line 75 - but only after the ES round-trip anddedup work.SubtasksAdd subtask** CHС м3 мс* ClaudeJir8 Jir3 CircleciA Sentry8• Tue 12 May 9:460 All BookmarksNikolay NikolovAneliya AngelovaReady for QA v4DetailsAssignee• Nikolay IvanovAssign to meReporterNikolay NikolovDevelopment|@ Open with VS Code1 branch8 commits1 pull request2 buildsComponentsPlatformSub-ProductAdd options* Improve Story3 othersNikolay Yankov4 days agoB3meet.googje.comNikolay Yanikov (You, presenti.9:46 AM | Daily - PlatformLukas Kovalik0:41...
|
NULL
|
2171105050369321660
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelp(ollDaily - Platform - now100% <28•Tue 12 May 9:46:34meet.google.com/mie-gawc-dsi?authuser=lukas.kovalik%40jiminny.com04 8:::Nikolay Yankov (Presenting, annotating)ChromeFileViewHistoryProfiesTabWindowHelp1 Sez JinX PrinryCo+ Atihttps://jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedissue=JY-20493© AWS|8 SSH Home | SalesforceDatadogPlatform TeamQ Sear$ Jy-9654 / П JY-20493|READY FISmart Instant Nudge Pre-filteringDescriptionProblem:E Nudge Feature Performance Recommendations | Problem #3: Instant Nudge Dispatch FloodSolution:Nudge Feature Performance Recommendations | Solution 2: Smart Instant Nudge Pre filtering (P1)|Process0rganisationInnediateNudges.Job.php:35-69For every AnalyticsCompletedEvent (one per new activity), the job loads every Activity\Search in the team that has atleast one instant nudge and dispatches ProcessNudgeSearchJob per nudge — without comparing the new activity to thesearch filters.ProcessNudgeSearchJob (ProcessNudgeSearchJob.php:42-98 ) then runs an ES onDenandSeroll plus a DB dedup chunk loop(NudgeRunFactory.php:195-225). When 0 new activities are found it bails on line 75 - but only after the ES round-trip anddedup work.SubtasksAdd subtask** CHС м3 мс* ClaudeJir8 Jir3 CircleciA Sentry8• Tue 12 May 9:460 All BookmarksNikolay NikolovAneliya AngelovaReady for QA v4DetailsAssignee• Nikolay IvanovAssign to meReporterNikolay NikolovDevelopment|@ Open with VS Code1 branch8 commits1 pull request2 buildsComponentsPlatformSub-ProductAdd options* Improve Story3 othersNikolay Yankov4 days agoB3meet.googje.comNikolay Yanikov (You, presenti.9:46 AM | Daily - PlatformLukas Kovalik0:41...
|
22049
|
NULL
|
NULL
|
NULL
|