|
79517
|
2786
|
41
|
2026-05-28T06:32:51.872795+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949971872_m1.jpg...
|
PhpStorm
|
faVsco.js – LayoutEntityTransformer.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
15
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Crm\Profile;
use League\Fractal\TransformerAbstract;
class LayoutEntityTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'children',
'field',
];
protected array $availableIncludes = [
'children',
'field',
];
private $profile;
private bool $noDefaultActivityTypeFollowUp = false;
private bool $noDefaultActivityType = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
}
public function setNoDefaultActivityType(bool $noDefaultActivityType)
{
$this->noDefaultActivityType = $noDefaultActivityType;
}
public function transform(LayoutEntity $entity): array
{
$label = $entity->getLabel();
$description = $entity->description;
$required = $entity->is_mandatory;
// Inherit from the base field.
$field = $entity->field;
if ($field) {
if ($label === null) {
$label = $field->label;
}
if ($description === null && $field->description) {
$description = $field->description;
}
if ($field->is_mandatory) {
$required = true;
}
}
return [
'id' => $entity->id_string,
'required' => $required,
'label' => $label,
'description' => $description,
'readOnly' => $entity->read_only,
'sequence' => $entity->sequence,
];
}
public function includeChildren(LayoutEntity $entity)
{
$children = $entity->children;
if ($children) {
$layoutEntityTransformer = new LayoutEntityTransformer($this->profile);
// Check if transforming a Follow Up section
if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {
$layoutEntityTransformer->setNoDefaultActivityType(true);
}
return $this->collection($children, $layoutEntityTransformer);
}
return null;
}
public function includeField(LayoutEntity $entity)
{
$field = $entity->field;
if ($field) {
$fieldTransformer = new FieldTransformer($this->profile);
// Check if transforming an Activity Type field
if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {
$fieldTransformer->setNoDefault(true);
}
return $this->item($field, $fieldTransformer);
}
return null;
}
}
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
21
1
18
2
6
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id
where u.team_id = 1;
SELECT * FROM social_accounts WHERE sociable_id = 1635;
SELECT * FROM users WHERE id = 1635;
select * from teams where id = 1;
select * from users where team_id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role;
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
SELECT * FROM automated_reports where id = 71;
SELECT * FROM automated_report_results where report_id = 71;
UPDATE automated_reports set playbook_categories = NULL where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT `automated_report_results`.* FROM `automated_report_results`
INNER JOIN `automated_reports`
ON `automated_report_results`.`report_id` = `automated_reports`.`id`
WHERE 1=1
AND `automated_report_results`.`generated_at` IS NOT NULL
# AND `automated_report_results`.`sent_at` IS NOT NULL
AND `automated_reports`.`team_id` = 1
AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$."users"')
;
SELECT * FROM automated_reports where id = 67;
SELECT * FROM automated_reports where id = 42;
SELECT * FROM users WHERE id = 143; # group 28
select * from teams where id = 3143;
select * from crm_configurations where id = 500;
select * from users where name = 'Integration Account'; # 1695
SELECT * FROM social_accounts WHERE sociable_id = 1695;
select * from activities where crm_configuration_id = 39
and recording_state = 'recorded' and duration > 60
and status = 'completed' and actual_start_time >= '2025-12-01';
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;
select * from leads;
SELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003
SELECT * FROM activities WHERE id IN (16,422003);
SELECT * FROM activities where status = 'failed';
SELECT * FROM tracks WHERE activity_id = 422003;
SELECT
a.*
FROM activities a
JOIN users u ON a.user_id = u.id
WHERE
a.status = 'completed'
AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid
AND a.deleted_at IS NULL
AND EXISTS (
SELECT 1 FROM tracks t
WHERE t.activity_id = a.id
AND t.type IN ('audio', 'video')
)
ORDER BY a.actual_start_time DESC
LIMIT 25;
select * from teams where id = 19;
select * from crm_configurations where provider = 'pipedrive';
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 = 19 and sa.provider = 'pipedrive';
SELECT * FROM social_accounts WHERE id = 1116;
UPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',
provider_refresh_token = '5034113:[TELEGRAM_TOKEN]b2bfc',
expires = 1779091997,
state = 'connected'
WHERE id = 1116;
"provider_user_token": "v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA",
"provider_refresh_token": "5034113:[TELEGRAM_TOKEN]b2bfc",
"expires": 1779091997,
select * from crm_field_values;
select * from crm_fields where type = 'multi-picklist';
SELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
SELECT * FROM crm_fields WHERE id = 3014; # 1885
SELECT * FROM crm_field_values WHERE crm_field_id = 3014;
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-20915-fix-missing-header-text-relay, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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":"TextRelayServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'TextRelayServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'TextRelayServiceTest'","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":"15","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutEntityTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'children',\n 'field',\n ];\n\n protected array $availableIncludes = [\n 'children',\n 'field',\n ];\n private $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n private bool $noDefaultActivityType = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n }\n\n public function setNoDefaultActivityType(bool $noDefaultActivityType)\n {\n $this->noDefaultActivityType = $noDefaultActivityType;\n }\n\n public function transform(LayoutEntity $entity): array\n {\n $label = $entity->getLabel();\n $description = $entity->description;\n $required = $entity->is_mandatory;\n\n // Inherit from the base field.\n $field = $entity->field;\n if ($field) {\n if ($label === null) {\n $label = $field->label;\n }\n\n if ($description === null && $field->description) {\n $description = $field->description;\n }\n\n if ($field->is_mandatory) {\n $required = true;\n }\n }\n\n return [\n 'id' => $entity->id_string,\n 'required' => $required,\n 'label' => $label,\n 'description' => $description,\n 'readOnly' => $entity->read_only,\n 'sequence' => $entity->sequence,\n ];\n }\n\n public function includeChildren(LayoutEntity $entity)\n {\n $children = $entity->children;\n if ($children) {\n $layoutEntityTransformer = new LayoutEntityTransformer($this->profile);\n\n // Check if transforming a Follow Up section\n if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {\n $layoutEntityTransformer->setNoDefaultActivityType(true);\n }\n\n return $this->collection($children, $layoutEntityTransformer);\n }\n\n return null;\n }\n\n public function includeField(LayoutEntity $entity)\n {\n $field = $entity->field;\n if ($field) {\n $fieldTransformer = new FieldTransformer($this->profile);\n\n // Check if transforming an Activity Type field\n if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {\n $fieldTransformer->setNoDefault(true);\n }\n\n return $this->item($field, $fieldTransformer);\n }\n\n return null;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutEntityTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'children',\n 'field',\n ];\n\n protected array $availableIncludes = [\n 'children',\n 'field',\n ];\n private $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n private bool $noDefaultActivityType = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n }\n\n public function setNoDefaultActivityType(bool $noDefaultActivityType)\n {\n $this->noDefaultActivityType = $noDefaultActivityType;\n }\n\n public function transform(LayoutEntity $entity): array\n {\n $label = $entity->getLabel();\n $description = $entity->description;\n $required = $entity->is_mandatory;\n\n // Inherit from the base field.\n $field = $entity->field;\n if ($field) {\n if ($label === null) {\n $label = $field->label;\n }\n\n if ($description === null && $field->description) {\n $description = $field->description;\n }\n\n if ($field->is_mandatory) {\n $required = true;\n }\n }\n\n return [\n 'id' => $entity->id_string,\n 'required' => $required,\n 'label' => $label,\n 'description' => $description,\n 'readOnly' => $entity->read_only,\n 'sequence' => $entity->sequence,\n ];\n }\n\n public function includeChildren(LayoutEntity $entity)\n {\n $children = $entity->children;\n if ($children) {\n $layoutEntityTransformer = new LayoutEntityTransformer($this->profile);\n\n // Check if transforming a Follow Up section\n if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {\n $layoutEntityTransformer->setNoDefaultActivityType(true);\n }\n\n return $this->collection($children, $layoutEntityTransformer);\n }\n\n return null;\n }\n\n public function includeField(LayoutEntity $entity)\n {\n $field = $entity->field;\n if ($field) {\n $fieldTransformer = new FieldTransformer($this->profile);\n\n // Check if transforming an Activity Type field\n if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {\n $fieldTransformer->setNoDefault(true);\n }\n\n return $this->item($field, $fieldTransformer);\n }\n\n return null;\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"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":"21","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"18","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"6","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\n\nselect sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id\nwhere u.team_id = 1;\nSELECT * FROM social_accounts WHERE sociable_id = 1635;\nSELECT * FROM users WHERE id = 1635;\n\nselect * from teams where id = 1;\nselect * from users where team_id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role;\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\nSELECT * FROM automated_reports where id = 71;\nSELECT * FROM automated_report_results where report_id = 71;\nUPDATE automated_reports set playbook_categories = NULL where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT `automated_report_results`.* FROM `automated_report_results`\nINNER JOIN `automated_reports`\n ON `automated_report_results`.`report_id` = `automated_reports`.`id`\nWHERE 1=1\n AND `automated_report_results`.`generated_at` IS NOT NULL\n# AND `automated_report_results`.`sent_at` IS NOT NULL\n AND `automated_reports`.`team_id` = 1\n AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$.\"users\"')\n;\n\nSELECT * FROM automated_reports where id = 67;\nSELECT * FROM automated_reports where id = 42;\nSELECT * FROM users WHERE id = 143; # group 28\n\nselect * from teams where id = 3143;\nselect * from crm_configurations where id = 500;\nselect * from users where name = 'Integration Account'; # 1695\nSELECT * FROM social_accounts WHERE sociable_id = 1695;\n\nselect * from activities where crm_configuration_id = 39\nand recording_state = 'recorded' and duration > 60\nand status = 'completed' and actual_start_time >= '2025-12-01';\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;\n\nselect * from leads;\n\nSELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003\nSELECT * FROM activities WHERE id IN (16,422003);\nSELECT * FROM activities where status = 'failed';\n\nSELECT * FROM tracks WHERE activity_id = 422003;\n\nSELECT\n a.*\nFROM activities a\nJOIN users u ON a.user_id = u.id\nWHERE\n a.status = 'completed'\n AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid\n AND a.deleted_at IS NULL\n AND EXISTS (\n SELECT 1 FROM tracks t\n WHERE t.activity_id = a.id\n AND t.type IN ('audio', 'video')\n )\nORDER BY a.actual_start_time DESC\nLIMIT 25;\n\nselect * from teams where id = 19;\nselect * from crm_configurations where provider = 'pipedrive';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 19 and sa.provider = 'pipedrive';\n\nSELECT * FROM social_accounts WHERE id = 1116;\n\nUPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',\nprovider_refresh_token = '5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc',\nexpires = 1779091997,\nstate = 'connected'\nWHERE id = 1116;\n\n \"provider_user_token\": \"v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA\",\n \"provider_refresh_token\": \"5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc\",\n \"expires\": 1779091997,\n\nselect * from crm_field_values;\n\nselect * from crm_fields where type = 'multi-picklist';\nSELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\nSELECT * FROM crm_fields WHERE id = 3014; # 1885\nSELECT * FROM crm_field_values WHERE crm_field_id = 3014;","depth":4,"on_screen":true,"value":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\n\nselect sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id\nwhere u.team_id = 1;\nSELECT * FROM social_accounts WHERE sociable_id = 1635;\nSELECT * FROM users WHERE id = 1635;\n\nselect * from teams where id = 1;\nselect * from users where team_id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role;\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\nSELECT * FROM automated_reports where id = 71;\nSELECT * FROM automated_report_results where report_id = 71;\nUPDATE automated_reports set playbook_categories = NULL where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT `automated_report_results`.* FROM `automated_report_results`\nINNER JOIN `automated_reports`\n ON `automated_report_results`.`report_id` = `automated_reports`.`id`\nWHERE 1=1\n AND `automated_report_results`.`generated_at` IS NOT NULL\n# AND `automated_report_results`.`sent_at` IS NOT NULL\n AND `automated_reports`.`team_id` = 1\n AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$.\"users\"')\n;\n\nSELECT * FROM automated_reports where id = 67;\nSELECT * FROM automated_reports where id = 42;\nSELECT * FROM users WHERE id = 143; # group 28\n\nselect * from teams where id = 3143;\nselect * from crm_configurations where id = 500;\nselect * from users where name = 'Integration Account'; # 1695\nSELECT * FROM social_accounts WHERE sociable_id = 1695;\n\nselect * from activities where crm_configuration_id = 39\nand recording_state = 'recorded' and duration > 60\nand status = 'completed' and actual_start_time >= '2025-12-01';\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;\n\nselect * from leads;\n\nSELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003\nSELECT * FROM activities WHERE id IN (16,422003);\nSELECT * FROM activities where status = 'failed';\n\nSELECT * FROM tracks WHERE activity_id = 422003;\n\nSELECT\n a.*\nFROM activities a\nJOIN users u ON a.user_id = u.id\nWHERE\n a.status = 'completed'\n AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid\n AND a.deleted_at IS NULL\n AND EXISTS (\n SELECT 1 FROM tracks t\n WHERE t.activity_id = a.id\n AND t.type IN ('audio', 'video')\n )\nORDER BY a.actual_start_time DESC\nLIMIT 25;\n\nselect * from teams where id = 19;\nselect * from crm_configurations where provider = 'pipedrive';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 19 and sa.provider = 'pipedrive';\n\nSELECT * FROM social_accounts WHERE id = 1116;\n\nUPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',\nprovider_refresh_token = '5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc',\nexpires = 1779091997,\nstate = 'connected'\nWHERE id = 1116;\n\n \"provider_user_token\": \"v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA\",\n \"provider_refresh_token\": \"5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc\",\n \"expires\": 1779091997,\n\nselect * from crm_field_values;\n\nselect * from crm_fields where type = 'multi-picklist';\nSELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\nSELECT * FROM crm_fields WHERE id = 3014; # 1885\nSELECT * FROM crm_field_values WHERE crm_field_id = 3014;","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}]...
|
-8777101628016391281
|
6830444471959033421
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
15
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Crm\Profile;
use League\Fractal\TransformerAbstract;
class LayoutEntityTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'children',
'field',
];
protected array $availableIncludes = [
'children',
'field',
];
private $profile;
private bool $noDefaultActivityTypeFollowUp = false;
private bool $noDefaultActivityType = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
}
public function setNoDefaultActivityType(bool $noDefaultActivityType)
{
$this->noDefaultActivityType = $noDefaultActivityType;
}
public function transform(LayoutEntity $entity): array
{
$label = $entity->getLabel();
$description = $entity->description;
$required = $entity->is_mandatory;
// Inherit from the base field.
$field = $entity->field;
if ($field) {
if ($label === null) {
$label = $field->label;
}
if ($description === null && $field->description) {
$description = $field->description;
}
if ($field->is_mandatory) {
$required = true;
}
}
return [
'id' => $entity->id_string,
'required' => $required,
'label' => $label,
'description' => $description,
'readOnly' => $entity->read_only,
'sequence' => $entity->sequence,
];
}
public function includeChildren(LayoutEntity $entity)
{
$children = $entity->children;
if ($children) {
$layoutEntityTransformer = new LayoutEntityTransformer($this->profile);
// Check if transforming a Follow Up section
if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {
$layoutEntityTransformer->setNoDefaultActivityType(true);
}
return $this->collection($children, $layoutEntityTransformer);
}
return null;
}
public function includeField(LayoutEntity $entity)
{
$field = $entity->field;
if ($field) {
$fieldTransformer = new FieldTransformer($this->profile);
// Check if transforming an Activity Type field
if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {
$fieldTransformer->setNoDefault(true);
}
return $this->item($field, $fieldTransformer);
}
return null;
}
}
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
21
1
18
2
6
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id
where u.team_id = 1;
SELECT * FROM social_accounts WHERE sociable_id = 1635;
SELECT * FROM users WHERE id = 1635;
select * from teams where id = 1;
select * from users where team_id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role;
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
SELECT * FROM automated_reports where id = 71;
SELECT * FROM automated_report_results where report_id = 71;
UPDATE automated_reports set playbook_categories = NULL where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT `automated_report_results`.* FROM `automated_report_results`
INNER JOIN `automated_reports`
ON `automated_report_results`.`report_id` = `automated_reports`.`id`
WHERE 1=1
AND `automated_report_results`.`generated_at` IS NOT NULL
# AND `automated_report_results`.`sent_at` IS NOT NULL
AND `automated_reports`.`team_id` = 1
AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$."users"')
;
SELECT * FROM automated_reports where id = 67;
SELECT * FROM automated_reports where id = 42;
SELECT * FROM users WHERE id = 143; # group 28
select * from teams where id = 3143;
select * from crm_configurations where id = 500;
select * from users where name = 'Integration Account'; # 1695
SELECT * FROM social_accounts WHERE sociable_id = 1695;
select * from activities where crm_configuration_id = 39
and recording_state = 'recorded' and duration > 60
and status = 'completed' and actual_start_time >= '2025-12-01';
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;
select * from leads;
SELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003
SELECT * FROM activities WHERE id IN (16,422003);
SELECT * FROM activities where status = 'failed';
SELECT * FROM tracks WHERE activity_id = 422003;
SELECT
a.*
FROM activities a
JOIN users u ON a.user_id = u.id
WHERE
a.status = 'completed'
AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid
AND a.deleted_at IS NULL
AND EXISTS (
SELECT 1 FROM tracks t
WHERE t.activity_id = a.id
AND t.type IN ('audio', 'video')
)
ORDER BY a.actual_start_time DESC
LIMIT 25;
select * from teams where id = 19;
select * from crm_configurations where provider = 'pipedrive';
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 = 19 and sa.provider = 'pipedrive';
SELECT * FROM social_accounts WHERE id = 1116;
UPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',
provider_refresh_token = '5034113:[TELEGRAM_TOKEN]b2bfc',
expires = 1779091997,
state = 'connected'
WHERE id = 1116;
"provider_user_token": "v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA",
"provider_refresh_token": "5034113:[TELEGRAM_TOKEN]b2bfc",
"expires": 1779091997,
select * from crm_field_values;
select * from crm_fields where type = 'multi-picklist';
SELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
SELECT * FROM crm_fields WHERE id = 3014; # 1885
SELECT * FROM crm_field_values WHERE crm_field_id = 3014;
Project
Project
New File or Directory…
Expand Selected
Collapse All...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79516
|
2787
|
67
|
2026-05-28T06:32:51.768972+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949971768_m2.jpg...
|
PhpStorm
|
faVsco.js – LayoutEntityTransformer.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
15
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Crm\Profile;
use League\Fractal\TransformerAbstract;
class LayoutEntityTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'children',
'field',
];
protected array $availableIncludes = [
'children',
'field',
];
private $profile;
private bool $noDefaultActivityTypeFollowUp = false;
private bool $noDefaultActivityType = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
}
public function setNoDefaultActivityType(bool $noDefaultActivityType)
{
$this->noDefaultActivityType = $noDefaultActivityType;
}
public function transform(LayoutEntity $entity): array
{
$label = $entity->getLabel();
$description = $entity->description;
$required = $entity->is_mandatory;
// Inherit from the base field.
$field = $entity->field;
if ($field) {
if ($label === null) {
$label = $field->label;
}
if ($description === null && $field->description) {
$description = $field->description;
}
if ($field->is_mandatory) {
$required = true;
}
}
return [
'id' => $entity->id_string,
'required' => $required,
'label' => $label,
'description' => $description,
'readOnly' => $entity->read_only,
'sequence' => $entity->sequence,
];
}
public function includeChildren(LayoutEntity $entity)
{
$children = $entity->children;
if ($children) {
$layoutEntityTransformer = new LayoutEntityTransformer($this->profile);
// Check if transforming a Follow Up section
if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {
$layoutEntityTransformer->setNoDefaultActivityType(true);
}
return $this->collection($children, $layoutEntityTransformer);
}
return null;
}
public function includeField(LayoutEntity $entity)
{
$field = $entity->field;
if ($field) {
$fieldTransformer = new FieldTransformer($this->profile);
// Check if transforming an Activity Type field
if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {
$fieldTransformer->setNoDefault(true);
}
return $this->item($field, $fieldTransformer);
}
return null;
}
}
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
21
1
18
2
6
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id
where u.team_id = 1;
SELECT * FROM social_accounts WHERE sociable_id = 1635;
SELECT * FROM users WHERE id = 1635;
select * from teams where id = 1;
select * from users where team_id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role;
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
SELECT * FROM automated_reports where id = 71;
SELECT * FROM automated_report_results where report_id = 71;
UPDATE automated_reports set playbook_categories = NULL where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT `automated_report_results`.* FROM `automated_report_results`
INNER JOIN `automated_reports`
ON `automated_report_results`.`report_id` = `automated_reports`.`id`
WHERE 1=1
AND `automated_report_results`.`generated_at` IS NOT NULL
# AND `automated_report_results`.`sent_at` IS NOT NULL
AND `automated_reports`.`team_id` = 1
AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$."users"')
;
SELECT * FROM automated_reports where id = 67;
SELECT * FROM automated_reports where id = 42;
SELECT * FROM users WHERE id = 143; # group 28
select * from teams where id = 3143;
select * from crm_configurations where id = 500;
select * from users where name = 'Integration Account'; # 1695
SELECT * FROM social_accounts WHERE sociable_id = 1695;
select * from activities where crm_configuration_id = 39
and recording_state = 'recorded' and duration > 60
and status = 'completed' and actual_start_time >= '2025-12-01';
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;
select * from leads;
SELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003
SELECT * FROM activities WHERE id IN (16,422003);
SELECT * FROM activities where status = 'failed';
SELECT * FROM tracks WHERE activity_id = 422003;
SELECT
a.*
FROM activities a
JOIN users u ON a.user_id = u.id
WHERE
a.status = 'completed'
AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid
AND a.deleted_at IS NULL
AND EXISTS (
SELECT 1 FROM tracks t
WHERE t.activity_id = a.id
AND t.type IN ('audio', 'video')
)
ORDER BY a.actual_start_time DESC
LIMIT 25;
select * from teams where id = 19;
select * from crm_configurations where provider = 'pipedrive';
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 = 19 and sa.provider = 'pipedrive';
SELECT * FROM social_accounts WHERE id = 1116;
UPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',
provider_refresh_token = '5034113:[TELEGRAM_TOKEN]b2bfc',
expires = 1779091997,
state = 'connected'
WHERE id = 1116;
"provider_user_token": "v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA",
"provider_refresh_token": "5034113:[TELEGRAM_TOKEN]b2bfc",
"expires": 1779091997,
select * from crm_field_values;
select * from crm_fields where type = 'multi-picklist';
SELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
SELECT * FROM crm_fields WHERE id = 3014; # 1885
SELECT * FROM crm_field_values WHERE crm_field_id = 3014;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
backend-code, folder
.env.staging
Dockerfile
start.sh
frontend-code, folder
worker-code, folder
worker-video-code, folder
config.yml, YAML file
config_continue.yml, YAML file
subenv_to_branch_map
workflows_prod.yml, YAML file
workflows_qa.yml, YAML file
workflows_qai.yml, YAML file
workflows_staging.yml, YAML file
workflows_subenv.yml, YAML file
.cursor, folder
.github
.sonarlint, folder
.vscode, folder
.windsurf, folder
app, sources root
Actions, folder
Component, folder...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09740692,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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.8374335,"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":"TextRelayServiceTest","depth":6,"bounds":{"left":0.85272604,"top":0.019952115,"width":0.062832445,"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 'TextRelayServiceTest'","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 'TextRelayServiceTest'","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":"15","depth":4,"bounds":{"left":0.37632978,"top":0.12529927,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.3879654,"top":0.12529927,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39694148,"top":0.123703115,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40425533,"top":0.123703115,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutEntityTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'children',\n 'field',\n ];\n\n protected array $availableIncludes = [\n 'children',\n 'field',\n ];\n private $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n private bool $noDefaultActivityType = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n }\n\n public function setNoDefaultActivityType(bool $noDefaultActivityType)\n {\n $this->noDefaultActivityType = $noDefaultActivityType;\n }\n\n public function transform(LayoutEntity $entity): array\n {\n $label = $entity->getLabel();\n $description = $entity->description;\n $required = $entity->is_mandatory;\n\n // Inherit from the base field.\n $field = $entity->field;\n if ($field) {\n if ($label === null) {\n $label = $field->label;\n }\n\n if ($description === null && $field->description) {\n $description = $field->description;\n }\n\n if ($field->is_mandatory) {\n $required = true;\n }\n }\n\n return [\n 'id' => $entity->id_string,\n 'required' => $required,\n 'label' => $label,\n 'description' => $description,\n 'readOnly' => $entity->read_only,\n 'sequence' => $entity->sequence,\n ];\n }\n\n public function includeChildren(LayoutEntity $entity)\n {\n $children = $entity->children;\n if ($children) {\n $layoutEntityTransformer = new LayoutEntityTransformer($this->profile);\n\n // Check if transforming a Follow Up section\n if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {\n $layoutEntityTransformer->setNoDefaultActivityType(true);\n }\n\n return $this->collection($children, $layoutEntityTransformer);\n }\n\n return null;\n }\n\n public function includeField(LayoutEntity $entity)\n {\n $field = $entity->field;\n if ($field) {\n $fieldTransformer = new FieldTransformer($this->profile);\n\n // Check if transforming an Activity Type field\n if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {\n $fieldTransformer->setNoDefault(true);\n }\n\n return $this->item($field, $fieldTransformer);\n }\n\n return null;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutEntityTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'children',\n 'field',\n ];\n\n protected array $availableIncludes = [\n 'children',\n 'field',\n ];\n private $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n private bool $noDefaultActivityType = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n }\n\n public function setNoDefaultActivityType(bool $noDefaultActivityType)\n {\n $this->noDefaultActivityType = $noDefaultActivityType;\n }\n\n public function transform(LayoutEntity $entity): array\n {\n $label = $entity->getLabel();\n $description = $entity->description;\n $required = $entity->is_mandatory;\n\n // Inherit from the base field.\n $field = $entity->field;\n if ($field) {\n if ($label === null) {\n $label = $field->label;\n }\n\n if ($description === null && $field->description) {\n $description = $field->description;\n }\n\n if ($field->is_mandatory) {\n $required = true;\n }\n }\n\n return [\n 'id' => $entity->id_string,\n 'required' => $required,\n 'label' => $label,\n 'description' => $description,\n 'readOnly' => $entity->read_only,\n 'sequence' => $entity->sequence,\n ];\n }\n\n public function includeChildren(LayoutEntity $entity)\n {\n $children = $entity->children;\n if ($children) {\n $layoutEntityTransformer = new LayoutEntityTransformer($this->profile);\n\n // Check if transforming a Follow Up section\n if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {\n $layoutEntityTransformer->setNoDefaultActivityType(true);\n }\n\n return $this->collection($children, $layoutEntityTransformer);\n }\n\n return null;\n }\n\n public function includeField(LayoutEntity $entity)\n {\n $field = $entity->field;\n if ($field) {\n $fieldTransformer = new FieldTransformer($this->profile);\n\n // Check if transforming an Activity Type field\n if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {\n $fieldTransformer->setNoDefault(true);\n }\n\n return $this->item($field, $fieldTransformer);\n }\n\n return null;\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"bounds":{"left":0.41289893,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"bounds":{"left":0.42154256,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"bounds":{"left":0.4325133,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"bounds":{"left":0.44115692,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"bounds":{"left":0.44980052,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"bounds":{"left":0.46077126,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"bounds":{"left":0.47174203,"top":0.09896249,"width":0.024268618,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"bounds":{"left":0.49833778,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"bounds":{"left":0.5093085,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7237367,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"21","depth":4,"bounds":{"left":0.6868351,"top":0.123703115,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.6984708,"top":0.123703115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"18","depth":4,"bounds":{"left":0.7077792,"top":0.123703115,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.7194149,"top":0.123703115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"6","depth":4,"bounds":{"left":0.7293883,"top":0.123703115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.7390292,"top":0.12210695,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.7463431,"top":0.12210695,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\n\nselect sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id\nwhere u.team_id = 1;\nSELECT * FROM social_accounts WHERE sociable_id = 1635;\nSELECT * FROM users WHERE id = 1635;\n\nselect * from teams where id = 1;\nselect * from users where team_id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role;\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\nSELECT * FROM automated_reports where id = 71;\nSELECT * FROM automated_report_results where report_id = 71;\nUPDATE automated_reports set playbook_categories = NULL where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT `automated_report_results`.* FROM `automated_report_results`\nINNER JOIN `automated_reports`\n ON `automated_report_results`.`report_id` = `automated_reports`.`id`\nWHERE 1=1\n AND `automated_report_results`.`generated_at` IS NOT NULL\n# AND `automated_report_results`.`sent_at` IS NOT NULL\n AND `automated_reports`.`team_id` = 1\n AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$.\"users\"')\n;\n\nSELECT * FROM automated_reports where id = 67;\nSELECT * FROM automated_reports where id = 42;\nSELECT * FROM users WHERE id = 143; # group 28\n\nselect * from teams where id = 3143;\nselect * from crm_configurations where id = 500;\nselect * from users where name = 'Integration Account'; # 1695\nSELECT * FROM social_accounts WHERE sociable_id = 1695;\n\nselect * from activities where crm_configuration_id = 39\nand recording_state = 'recorded' and duration > 60\nand status = 'completed' and actual_start_time >= '2025-12-01';\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;\n\nselect * from leads;\n\nSELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003\nSELECT * FROM activities WHERE id IN (16,422003);\nSELECT * FROM activities where status = 'failed';\n\nSELECT * FROM tracks WHERE activity_id = 422003;\n\nSELECT\n a.*\nFROM activities a\nJOIN users u ON a.user_id = u.id\nWHERE\n a.status = 'completed'\n AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid\n AND a.deleted_at IS NULL\n AND EXISTS (\n SELECT 1 FROM tracks t\n WHERE t.activity_id = a.id\n AND t.type IN ('audio', 'video')\n )\nORDER BY a.actual_start_time DESC\nLIMIT 25;\n\nselect * from teams where id = 19;\nselect * from crm_configurations where provider = 'pipedrive';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 19 and sa.provider = 'pipedrive';\n\nSELECT * FROM social_accounts WHERE id = 1116;\n\nUPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',\nprovider_refresh_token = '5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc',\nexpires = 1779091997,\nstate = 'connected'\nWHERE id = 1116;\n\n \"provider_user_token\": \"v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA\",\n \"provider_refresh_token\": \"5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc\",\n \"expires\": 1779091997,\n\nselect * from crm_field_values;\n\nselect * from crm_fields where type = 'multi-picklist';\nSELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\nSELECT * FROM crm_fields WHERE id = 3014; # 1885\nSELECT * FROM crm_field_values WHERE crm_field_id = 3014;","depth":4,"on_screen":true,"value":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\n\nselect sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id\nwhere u.team_id = 1;\nSELECT * FROM social_accounts WHERE sociable_id = 1635;\nSELECT * FROM users WHERE id = 1635;\n\nselect * from teams where id = 1;\nselect * from users where team_id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role;\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\nSELECT * FROM automated_reports where id = 71;\nSELECT * FROM automated_report_results where report_id = 71;\nUPDATE automated_reports set playbook_categories = NULL where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT `automated_report_results`.* FROM `automated_report_results`\nINNER JOIN `automated_reports`\n ON `automated_report_results`.`report_id` = `automated_reports`.`id`\nWHERE 1=1\n AND `automated_report_results`.`generated_at` IS NOT NULL\n# AND `automated_report_results`.`sent_at` IS NOT NULL\n AND `automated_reports`.`team_id` = 1\n AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$.\"users\"')\n;\n\nSELECT * FROM automated_reports where id = 67;\nSELECT * FROM automated_reports where id = 42;\nSELECT * FROM users WHERE id = 143; # group 28\n\nselect * from teams where id = 3143;\nselect * from crm_configurations where id = 500;\nselect * from users where name = 'Integration Account'; # 1695\nSELECT * FROM social_accounts WHERE sociable_id = 1695;\n\nselect * from activities where crm_configuration_id = 39\nand recording_state = 'recorded' and duration > 60\nand status = 'completed' and actual_start_time >= '2025-12-01';\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;\n\nselect * from leads;\n\nSELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003\nSELECT * FROM activities WHERE id IN (16,422003);\nSELECT * FROM activities where status = 'failed';\n\nSELECT * FROM tracks WHERE activity_id = 422003;\n\nSELECT\n a.*\nFROM activities a\nJOIN users u ON a.user_id = u.id\nWHERE\n a.status = 'completed'\n AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid\n AND a.deleted_at IS NULL\n AND EXISTS (\n SELECT 1 FROM tracks t\n WHERE t.activity_id = a.id\n AND t.type IN ('audio', 'video')\n )\nORDER BY a.actual_start_time DESC\nLIMIT 25;\n\nselect * from teams where id = 19;\nselect * from crm_configurations where provider = 'pipedrive';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 19 and sa.provider = 'pipedrive';\n\nSELECT * FROM social_accounts WHERE id = 1116;\n\nUPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',\nprovider_refresh_token = '5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc',\nexpires = 1779091997,\nstate = 'connected'\nWHERE id = 1116;\n\n \"provider_user_token\": \"v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA\",\n \"provider_refresh_token\": \"5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc\",\n \"expires\": 1779091997,\n\nselect * from crm_field_values;\n\nselect * from crm_fields where type = 'multi-picklist';\nSELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\nSELECT * FROM crm_fields WHERE id = 3014; # 1885\nSELECT * FROM crm_field_values WHERE crm_field_id = 3014;","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},{"role":"AXStaticText","text":"app ~/jiminny/app, folder","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci, folder","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend-code, folder","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".env.staging","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dockerfile","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"start.sh","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"frontend-code, folder","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"worker-code, folder","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"worker-video-code, folder","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"config.yml, YAML file","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"config_continue.yml, YAML file","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"subenv_to_branch_map","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"workflows_prod.yml, YAML file","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"workflows_qa.yml, YAML file","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"workflows_qai.yml, YAML file","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"workflows_staging.yml, YAML file","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"workflows_subenv.yml, YAML file","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor, folder","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint, folder","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode, folder","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf, folder","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions, folder","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component, folder","depth":8,"on_screen":false,"role_description":"text"}]...
|
5697895504486911141
|
6830444471959033421
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
15
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Crm\Profile;
use League\Fractal\TransformerAbstract;
class LayoutEntityTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'children',
'field',
];
protected array $availableIncludes = [
'children',
'field',
];
private $profile;
private bool $noDefaultActivityTypeFollowUp = false;
private bool $noDefaultActivityType = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
}
public function setNoDefaultActivityType(bool $noDefaultActivityType)
{
$this->noDefaultActivityType = $noDefaultActivityType;
}
public function transform(LayoutEntity $entity): array
{
$label = $entity->getLabel();
$description = $entity->description;
$required = $entity->is_mandatory;
// Inherit from the base field.
$field = $entity->field;
if ($field) {
if ($label === null) {
$label = $field->label;
}
if ($description === null && $field->description) {
$description = $field->description;
}
if ($field->is_mandatory) {
$required = true;
}
}
return [
'id' => $entity->id_string,
'required' => $required,
'label' => $label,
'description' => $description,
'readOnly' => $entity->read_only,
'sequence' => $entity->sequence,
];
}
public function includeChildren(LayoutEntity $entity)
{
$children = $entity->children;
if ($children) {
$layoutEntityTransformer = new LayoutEntityTransformer($this->profile);
// Check if transforming a Follow Up section
if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {
$layoutEntityTransformer->setNoDefaultActivityType(true);
}
return $this->collection($children, $layoutEntityTransformer);
}
return null;
}
public function includeField(LayoutEntity $entity)
{
$field = $entity->field;
if ($field) {
$fieldTransformer = new FieldTransformer($this->profile);
// Check if transforming an Activity Type field
if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {
$fieldTransformer->setNoDefault(true);
}
return $this->item($field, $fieldTransformer);
}
return null;
}
}
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
21
1
18
2
6
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id
where u.team_id = 1;
SELECT * FROM social_accounts WHERE sociable_id = 1635;
SELECT * FROM users WHERE id = 1635;
select * from teams where id = 1;
select * from users where team_id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role;
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
SELECT * FROM automated_reports where id = 71;
SELECT * FROM automated_report_results where report_id = 71;
UPDATE automated_reports set playbook_categories = NULL where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT `automated_report_results`.* FROM `automated_report_results`
INNER JOIN `automated_reports`
ON `automated_report_results`.`report_id` = `automated_reports`.`id`
WHERE 1=1
AND `automated_report_results`.`generated_at` IS NOT NULL
# AND `automated_report_results`.`sent_at` IS NOT NULL
AND `automated_reports`.`team_id` = 1
AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$."users"')
;
SELECT * FROM automated_reports where id = 67;
SELECT * FROM automated_reports where id = 42;
SELECT * FROM users WHERE id = 143; # group 28
select * from teams where id = 3143;
select * from crm_configurations where id = 500;
select * from users where name = 'Integration Account'; # 1695
SELECT * FROM social_accounts WHERE sociable_id = 1695;
select * from activities where crm_configuration_id = 39
and recording_state = 'recorded' and duration > 60
and status = 'completed' and actual_start_time >= '2025-12-01';
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;
select * from leads;
SELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003
SELECT * FROM activities WHERE id IN (16,422003);
SELECT * FROM activities where status = 'failed';
SELECT * FROM tracks WHERE activity_id = 422003;
SELECT
a.*
FROM activities a
JOIN users u ON a.user_id = u.id
WHERE
a.status = 'completed'
AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid
AND a.deleted_at IS NULL
AND EXISTS (
SELECT 1 FROM tracks t
WHERE t.activity_id = a.id
AND t.type IN ('audio', 'video')
)
ORDER BY a.actual_start_time DESC
LIMIT 25;
select * from teams where id = 19;
select * from crm_configurations where provider = 'pipedrive';
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 = 19 and sa.provider = 'pipedrive';
SELECT * FROM social_accounts WHERE id = 1116;
UPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',
provider_refresh_token = '5034113:[TELEGRAM_TOKEN]b2bfc',
expires = 1779091997,
state = 'connected'
WHERE id = 1116;
"provider_user_token": "v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA",
"provider_refresh_token": "5034113:[TELEGRAM_TOKEN]b2bfc",
"expires": 1779091997,
select * from crm_field_values;
select * from crm_fields where type = 'multi-picklist';
SELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
SELECT * FROM crm_fields WHERE id = 3014; # 1885
SELECT * FROM crm_field_values WHERE crm_field_id = 3014;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
backend-code, folder
.env.staging
Dockerfile
start.sh
frontend-code, folder
worker-code, folder
worker-video-code, folder
config.yml, YAML file
config_continue.yml, YAML file
subenv_to_branch_map
workflows_prod.yml, YAML file
workflows_qa.yml, YAML file
workflows_qai.yml, YAML file
workflows_staging.yml, YAML file
workflows_subenv.yml, YAML file
.cursor, folder
.github
.sonarlint, folder
.vscode, folder
.windsurf, folder
app, sources root
Actions, folder
Component, folder...
|
79515
|
NULL
|
NULL
|
NULL
|
|
79515
|
2787
|
66
|
2026-05-28T06:32:51.338491+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949971338_m2.jpg...
|
PhpStorm
|
faVsco.js – LayoutEntityTransformer.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
15
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Crm\Profile;
use League\Fractal\TransformerAbstract;
class LayoutEntityTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'children',
'field',
];
protected array $availableIncludes = [
'children',
'field',
];
private $profile;
private bool $noDefaultActivityTypeFollowUp = false;
private bool $noDefaultActivityType = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
}
public function setNoDefaultActivityType(bool $noDefaultActivityType)
{
$this->noDefaultActivityType = $noDefaultActivityType;
}
public function transform(LayoutEntity $entity): array
{
$label = $entity->getLabel();
$description = $entity->description;
$required = $entity->is_mandatory;
// Inherit from the base field.
$field = $entity->field;
if ($field) {
if ($label === null) {
$label = $field->label;
}
if ($description === null && $field->description) {
$description = $field->description;
}
if ($field->is_mandatory) {
$required = true;
}
}
return [
'id' => $entity->id_string,
'required' => $required,
'label' => $label,
'description' => $description,
'readOnly' => $entity->read_only,
'sequence' => $entity->sequence,
];
}
public function includeChildren(LayoutEntity $entity)
{
$children = $entity->children;
if ($children) {
$layoutEntityTransformer = new LayoutEntityTransformer($this->profile);
// Check if transforming a Follow Up section
if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {
$layoutEntityTransformer->setNoDefaultActivityType(true);
}
return $this->collection($children, $layoutEntityTransformer);
}
return null;
}
public function includeField(LayoutEntity $entity)
{
$field = $entity->field;
if ($field) {
$fieldTransformer = new FieldTransformer($this->profile);
// Check if transforming an Activity Type field
if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {
$fieldTransformer->setNoDefault(true);
}
return $this->item($field, $fieldTransformer);
}
return null;
}
}
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
21
1
18
2
6
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id
where u.team_id = 1;
SELECT * FROM social_accounts WHERE sociable_id = 1635;
SELECT * FROM users WHERE id = 1635;
select * from teams where id = 1;
select * from users where team_id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role;
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
SELECT * FROM automated_reports where id = 71;
SELECT * FROM automated_report_results where report_id = 71;
UPDATE automated_reports set playbook_categories = NULL where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT `automated_report_results`.* FROM `automated_report_results`
INNER JOIN `automated_reports`
ON `automated_report_results`.`report_id` = `automated_reports`.`id`
WHERE 1=1
AND `automated_report_results`.`generated_at` IS NOT NULL
# AND `automated_report_results`.`sent_at` IS NOT NULL
AND `automated_reports`.`team_id` = 1
AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$."users"')
;
SELECT * FROM automated_reports where id = 67;
SELECT * FROM automated_reports where id = 42;
SELECT * FROM users WHERE id = 143; # group 28
select * from teams where id = 3143;
select * from crm_configurations where id = 500;
select * from users where name = 'Integration Account'; # 1695
SELECT * FROM social_accounts WHERE sociable_id = 1695;
select * from activities where crm_configuration_id = 39
and recording_state = 'recorded' and duration > 60
and status = 'completed' and actual_start_time >= '2025-12-01';
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;
select * from leads;
SELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003
SELECT * FROM activities WHERE id IN (16,422003);
SELECT * FROM activities where status = 'failed';
SELECT * FROM tracks WHERE activity_id = 422003;
SELECT
a.*
FROM activities a
JOIN users u ON a.user_id = u.id
WHERE
a.status = 'completed'
AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid
AND a.deleted_at IS NULL
AND EXISTS (
SELECT 1 FROM tracks t
WHERE t.activity_id = a.id
AND t.type IN ('audio', 'video')
)
ORDER BY a.actual_start_time DESC
LIMIT 25;
select * from teams where id = 19;
select * from crm_configurations where provider = 'pipedrive';
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 = 19 and sa.provider = 'pipedrive';
SELECT * FROM social_accounts WHERE id = 1116;
UPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',
provider_refresh_token = '5034113:[TELEGRAM_TOKEN]b2bfc',
expires = 1779091997,
state = 'connected'
WHERE id = 1116;
"provider_user_token": "v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA",
"provider_refresh_token": "5034113:[TELEGRAM_TOKEN]b2bfc",
"expires": 1779091997,
select * from crm_field_values;
select * from crm_fields where type = 'multi-picklist';
SELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
SELECT * FROM crm_fields WHERE id = 3014; # 1885
SELECT * FROM crm_field_values WHERE crm_field_id = 3014;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
backend-code, folder
.env.staging
Dockerfile
start.sh
frontend-code, folder
worker-code, folder
worker-video-code, folder
config.yml, YAML file
config_continue.yml, YAML file
subenv_to_branch_map
workflows_prod.yml, YAML file
workflows_qa.yml, YAML file
workflows_qai.yml, YAML file...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09740692,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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.8374335,"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":"TextRelayServiceTest","depth":6,"bounds":{"left":0.85272604,"top":0.019952115,"width":0.062832445,"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 'TextRelayServiceTest'","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 'TextRelayServiceTest'","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":"15","depth":4,"bounds":{"left":0.37632978,"top":0.12529927,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.3879654,"top":0.12529927,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39694148,"top":0.123703115,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40425533,"top":0.123703115,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutEntityTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'children',\n 'field',\n ];\n\n protected array $availableIncludes = [\n 'children',\n 'field',\n ];\n private $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n private bool $noDefaultActivityType = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n }\n\n public function setNoDefaultActivityType(bool $noDefaultActivityType)\n {\n $this->noDefaultActivityType = $noDefaultActivityType;\n }\n\n public function transform(LayoutEntity $entity): array\n {\n $label = $entity->getLabel();\n $description = $entity->description;\n $required = $entity->is_mandatory;\n\n // Inherit from the base field.\n $field = $entity->field;\n if ($field) {\n if ($label === null) {\n $label = $field->label;\n }\n\n if ($description === null && $field->description) {\n $description = $field->description;\n }\n\n if ($field->is_mandatory) {\n $required = true;\n }\n }\n\n return [\n 'id' => $entity->id_string,\n 'required' => $required,\n 'label' => $label,\n 'description' => $description,\n 'readOnly' => $entity->read_only,\n 'sequence' => $entity->sequence,\n ];\n }\n\n public function includeChildren(LayoutEntity $entity)\n {\n $children = $entity->children;\n if ($children) {\n $layoutEntityTransformer = new LayoutEntityTransformer($this->profile);\n\n // Check if transforming a Follow Up section\n if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {\n $layoutEntityTransformer->setNoDefaultActivityType(true);\n }\n\n return $this->collection($children, $layoutEntityTransformer);\n }\n\n return null;\n }\n\n public function includeField(LayoutEntity $entity)\n {\n $field = $entity->field;\n if ($field) {\n $fieldTransformer = new FieldTransformer($this->profile);\n\n // Check if transforming an Activity Type field\n if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {\n $fieldTransformer->setNoDefault(true);\n }\n\n return $this->item($field, $fieldTransformer);\n }\n\n return null;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutEntityTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'children',\n 'field',\n ];\n\n protected array $availableIncludes = [\n 'children',\n 'field',\n ];\n private $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n private bool $noDefaultActivityType = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n }\n\n public function setNoDefaultActivityType(bool $noDefaultActivityType)\n {\n $this->noDefaultActivityType = $noDefaultActivityType;\n }\n\n public function transform(LayoutEntity $entity): array\n {\n $label = $entity->getLabel();\n $description = $entity->description;\n $required = $entity->is_mandatory;\n\n // Inherit from the base field.\n $field = $entity->field;\n if ($field) {\n if ($label === null) {\n $label = $field->label;\n }\n\n if ($description === null && $field->description) {\n $description = $field->description;\n }\n\n if ($field->is_mandatory) {\n $required = true;\n }\n }\n\n return [\n 'id' => $entity->id_string,\n 'required' => $required,\n 'label' => $label,\n 'description' => $description,\n 'readOnly' => $entity->read_only,\n 'sequence' => $entity->sequence,\n ];\n }\n\n public function includeChildren(LayoutEntity $entity)\n {\n $children = $entity->children;\n if ($children) {\n $layoutEntityTransformer = new LayoutEntityTransformer($this->profile);\n\n // Check if transforming a Follow Up section\n if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {\n $layoutEntityTransformer->setNoDefaultActivityType(true);\n }\n\n return $this->collection($children, $layoutEntityTransformer);\n }\n\n return null;\n }\n\n public function includeField(LayoutEntity $entity)\n {\n $field = $entity->field;\n if ($field) {\n $fieldTransformer = new FieldTransformer($this->profile);\n\n // Check if transforming an Activity Type field\n if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {\n $fieldTransformer->setNoDefault(true);\n }\n\n return $this->item($field, $fieldTransformer);\n }\n\n return null;\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"bounds":{"left":0.41289893,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"bounds":{"left":0.42154256,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"bounds":{"left":0.4325133,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"bounds":{"left":0.44115692,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"bounds":{"left":0.44980052,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"bounds":{"left":0.46077126,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"bounds":{"left":0.47174203,"top":0.09896249,"width":0.024268618,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"bounds":{"left":0.49833778,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"bounds":{"left":0.5093085,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7237367,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"21","depth":4,"bounds":{"left":0.6868351,"top":0.123703115,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.6984708,"top":0.123703115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"18","depth":4,"bounds":{"left":0.7077792,"top":0.123703115,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.7194149,"top":0.123703115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"6","depth":4,"bounds":{"left":0.7293883,"top":0.123703115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.7390292,"top":0.12210695,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.7463431,"top":0.12210695,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\n\nselect sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id\nwhere u.team_id = 1;\nSELECT * FROM social_accounts WHERE sociable_id = 1635;\nSELECT * FROM users WHERE id = 1635;\n\nselect * from teams where id = 1;\nselect * from users where team_id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role;\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\nSELECT * FROM automated_reports where id = 71;\nSELECT * FROM automated_report_results where report_id = 71;\nUPDATE automated_reports set playbook_categories = NULL where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT `automated_report_results`.* FROM `automated_report_results`\nINNER JOIN `automated_reports`\n ON `automated_report_results`.`report_id` = `automated_reports`.`id`\nWHERE 1=1\n AND `automated_report_results`.`generated_at` IS NOT NULL\n# AND `automated_report_results`.`sent_at` IS NOT NULL\n AND `automated_reports`.`team_id` = 1\n AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$.\"users\"')\n;\n\nSELECT * FROM automated_reports where id = 67;\nSELECT * FROM automated_reports where id = 42;\nSELECT * FROM users WHERE id = 143; # group 28\n\nselect * from teams where id = 3143;\nselect * from crm_configurations where id = 500;\nselect * from users where name = 'Integration Account'; # 1695\nSELECT * FROM social_accounts WHERE sociable_id = 1695;\n\nselect * from activities where crm_configuration_id = 39\nand recording_state = 'recorded' and duration > 60\nand status = 'completed' and actual_start_time >= '2025-12-01';\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;\n\nselect * from leads;\n\nSELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003\nSELECT * FROM activities WHERE id IN (16,422003);\nSELECT * FROM activities where status = 'failed';\n\nSELECT * FROM tracks WHERE activity_id = 422003;\n\nSELECT\n a.*\nFROM activities a\nJOIN users u ON a.user_id = u.id\nWHERE\n a.status = 'completed'\n AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid\n AND a.deleted_at IS NULL\n AND EXISTS (\n SELECT 1 FROM tracks t\n WHERE t.activity_id = a.id\n AND t.type IN ('audio', 'video')\n )\nORDER BY a.actual_start_time DESC\nLIMIT 25;\n\nselect * from teams where id = 19;\nselect * from crm_configurations where provider = 'pipedrive';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 19 and sa.provider = 'pipedrive';\n\nSELECT * FROM social_accounts WHERE id = 1116;\n\nUPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',\nprovider_refresh_token = '5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc',\nexpires = 1779091997,\nstate = 'connected'\nWHERE id = 1116;\n\n \"provider_user_token\": \"v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA\",\n \"provider_refresh_token\": \"5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc\",\n \"expires\": 1779091997,\n\nselect * from crm_field_values;\n\nselect * from crm_fields where type = 'multi-picklist';\nSELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\nSELECT * FROM crm_fields WHERE id = 3014; # 1885\nSELECT * FROM crm_field_values WHERE crm_field_id = 3014;","depth":4,"on_screen":true,"value":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\n\nselect sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id\nwhere u.team_id = 1;\nSELECT * FROM social_accounts WHERE sociable_id = 1635;\nSELECT * FROM users WHERE id = 1635;\n\nselect * from teams where id = 1;\nselect * from users where team_id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role;\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\nSELECT * FROM automated_reports where id = 71;\nSELECT * FROM automated_report_results where report_id = 71;\nUPDATE automated_reports set playbook_categories = NULL where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT `automated_report_results`.* FROM `automated_report_results`\nINNER JOIN `automated_reports`\n ON `automated_report_results`.`report_id` = `automated_reports`.`id`\nWHERE 1=1\n AND `automated_report_results`.`generated_at` IS NOT NULL\n# AND `automated_report_results`.`sent_at` IS NOT NULL\n AND `automated_reports`.`team_id` = 1\n AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$.\"users\"')\n;\n\nSELECT * FROM automated_reports where id = 67;\nSELECT * FROM automated_reports where id = 42;\nSELECT * FROM users WHERE id = 143; # group 28\n\nselect * from teams where id = 3143;\nselect * from crm_configurations where id = 500;\nselect * from users where name = 'Integration Account'; # 1695\nSELECT * FROM social_accounts WHERE sociable_id = 1695;\n\nselect * from activities where crm_configuration_id = 39\nand recording_state = 'recorded' and duration > 60\nand status = 'completed' and actual_start_time >= '2025-12-01';\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;\n\nselect * from leads;\n\nSELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003\nSELECT * FROM activities WHERE id IN (16,422003);\nSELECT * FROM activities where status = 'failed';\n\nSELECT * FROM tracks WHERE activity_id = 422003;\n\nSELECT\n a.*\nFROM activities a\nJOIN users u ON a.user_id = u.id\nWHERE\n a.status = 'completed'\n AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid\n AND a.deleted_at IS NULL\n AND EXISTS (\n SELECT 1 FROM tracks t\n WHERE t.activity_id = a.id\n AND t.type IN ('audio', 'video')\n )\nORDER BY a.actual_start_time DESC\nLIMIT 25;\n\nselect * from teams where id = 19;\nselect * from crm_configurations where provider = 'pipedrive';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 19 and sa.provider = 'pipedrive';\n\nSELECT * FROM social_accounts WHERE id = 1116;\n\nUPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',\nprovider_refresh_token = '5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc',\nexpires = 1779091997,\nstate = 'connected'\nWHERE id = 1116;\n\n \"provider_user_token\": \"v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA\",\n \"provider_refresh_token\": \"5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc\",\n \"expires\": 1779091997,\n\nselect * from crm_field_values;\n\nselect * from crm_fields where type = 'multi-picklist';\nSELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\nSELECT * FROM crm_fields WHERE id = 3014; # 1885\nSELECT * FROM crm_field_values WHERE crm_field_id = 3014;","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},{"role":"AXStaticText","text":"app ~/jiminny/app, folder","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci, folder","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend-code, folder","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".env.staging","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dockerfile","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"start.sh","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"frontend-code, folder","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"worker-code, folder","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"worker-video-code, folder","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"config.yml, YAML file","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"config_continue.yml, YAML file","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"subenv_to_branch_map","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"workflows_prod.yml, YAML file","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"workflows_qa.yml, YAML file","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"workflows_qai.yml, YAML file","depth":8,"on_screen":false,"role_description":"text"}]...
|
-6655060240805174613
|
6830444471959033421
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
15
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Crm\Profile;
use League\Fractal\TransformerAbstract;
class LayoutEntityTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'children',
'field',
];
protected array $availableIncludes = [
'children',
'field',
];
private $profile;
private bool $noDefaultActivityTypeFollowUp = false;
private bool $noDefaultActivityType = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
}
public function setNoDefaultActivityType(bool $noDefaultActivityType)
{
$this->noDefaultActivityType = $noDefaultActivityType;
}
public function transform(LayoutEntity $entity): array
{
$label = $entity->getLabel();
$description = $entity->description;
$required = $entity->is_mandatory;
// Inherit from the base field.
$field = $entity->field;
if ($field) {
if ($label === null) {
$label = $field->label;
}
if ($description === null && $field->description) {
$description = $field->description;
}
if ($field->is_mandatory) {
$required = true;
}
}
return [
'id' => $entity->id_string,
'required' => $required,
'label' => $label,
'description' => $description,
'readOnly' => $entity->read_only,
'sequence' => $entity->sequence,
];
}
public function includeChildren(LayoutEntity $entity)
{
$children = $entity->children;
if ($children) {
$layoutEntityTransformer = new LayoutEntityTransformer($this->profile);
// Check if transforming a Follow Up section
if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {
$layoutEntityTransformer->setNoDefaultActivityType(true);
}
return $this->collection($children, $layoutEntityTransformer);
}
return null;
}
public function includeField(LayoutEntity $entity)
{
$field = $entity->field;
if ($field) {
$fieldTransformer = new FieldTransformer($this->profile);
// Check if transforming an Activity Type field
if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {
$fieldTransformer->setNoDefault(true);
}
return $this->item($field, $fieldTransformer);
}
return null;
}
}
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
21
1
18
2
6
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id
where u.team_id = 1;
SELECT * FROM social_accounts WHERE sociable_id = 1635;
SELECT * FROM users WHERE id = 1635;
select * from teams where id = 1;
select * from users where team_id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role;
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
SELECT * FROM automated_reports where id = 71;
SELECT * FROM automated_report_results where report_id = 71;
UPDATE automated_reports set playbook_categories = NULL where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT `automated_report_results`.* FROM `automated_report_results`
INNER JOIN `automated_reports`
ON `automated_report_results`.`report_id` = `automated_reports`.`id`
WHERE 1=1
AND `automated_report_results`.`generated_at` IS NOT NULL
# AND `automated_report_results`.`sent_at` IS NOT NULL
AND `automated_reports`.`team_id` = 1
AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$."users"')
;
SELECT * FROM automated_reports where id = 67;
SELECT * FROM automated_reports where id = 42;
SELECT * FROM users WHERE id = 143; # group 28
select * from teams where id = 3143;
select * from crm_configurations where id = 500;
select * from users where name = 'Integration Account'; # 1695
SELECT * FROM social_accounts WHERE sociable_id = 1695;
select * from activities where crm_configuration_id = 39
and recording_state = 'recorded' and duration > 60
and status = 'completed' and actual_start_time >= '2025-12-01';
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;
select * from leads;
SELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003
SELECT * FROM activities WHERE id IN (16,422003);
SELECT * FROM activities where status = 'failed';
SELECT * FROM tracks WHERE activity_id = 422003;
SELECT
a.*
FROM activities a
JOIN users u ON a.user_id = u.id
WHERE
a.status = 'completed'
AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid
AND a.deleted_at IS NULL
AND EXISTS (
SELECT 1 FROM tracks t
WHERE t.activity_id = a.id
AND t.type IN ('audio', 'video')
)
ORDER BY a.actual_start_time DESC
LIMIT 25;
select * from teams where id = 19;
select * from crm_configurations where provider = 'pipedrive';
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 = 19 and sa.provider = 'pipedrive';
SELECT * FROM social_accounts WHERE id = 1116;
UPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',
provider_refresh_token = '5034113:[TELEGRAM_TOKEN]b2bfc',
expires = 1779091997,
state = 'connected'
WHERE id = 1116;
"provider_user_token": "v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA",
"provider_refresh_token": "5034113:[TELEGRAM_TOKEN]b2bfc",
"expires": 1779091997,
select * from crm_field_values;
select * from crm_fields where type = 'multi-picklist';
SELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
SELECT * FROM crm_fields WHERE id = 3014; # 1885
SELECT * FROM crm_field_values WHERE crm_field_id = 3014;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
backend-code, folder
.env.staging
Dockerfile
start.sh
frontend-code, folder
worker-code, folder
worker-video-code, folder
config.yml, YAML file
config_continue.yml, YAML file
subenv_to_branch_map
workflows_prod.yml, YAML file
workflows_qa.yml, YAML file
workflows_qai.yml, YAML file...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79514
|
2787
|
65
|
2026-05-28T06:32:50.403676+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949970403_m2.jpg...
|
PhpStorm
|
faVsco.js – LayoutEntityTransformer.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
15
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Crm\Profile;
use League\Fractal\TransformerAbstract;
class LayoutEntityTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'children',
'field',
];
protected array $availableIncludes = [
'children',
'field',
];
private $profile;
private bool $noDefaultActivityTypeFollowUp = false;
private bool $noDefaultActivityType = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
}
public function setNoDefaultActivityType(bool $noDefaultActivityType)
{
$this->noDefaultActivityType = $noDefaultActivityType;
}
public function transform(LayoutEntity $entity): array
{
$label = $entity->getLabel();
$description = $entity->description;
$required = $entity->is_mandatory;
// Inherit from the base field.
$field = $entity->field;
if ($field) {
if ($label === null) {
$label = $field->label;
}
if ($description === null && $field->description) {
$description = $field->description;
}
if ($field->is_mandatory) {
$required = true;
}
}
return [
'id' => $entity->id_string,
'required' => $required,
'label' => $label,
'description' => $description,
'readOnly' => $entity->read_only,
'sequence' => $entity->sequence,
];
}
public function includeChildren(LayoutEntity $entity)
{
$children = $entity->children;
if ($children) {
$layoutEntityTransformer = new LayoutEntityTransformer($this->profile);
// Check if transforming a Follow Up section
if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {
$layoutEntityTransformer->setNoDefaultActivityType(true);
}
return $this->collection($children, $layoutEntityTransformer);
}
return null;
}
public function includeField(LayoutEntity $entity)
{
$field = $entity->field;
if ($field) {
$fieldTransformer = new FieldTransformer($this->profile);
// Check if transforming an Activity Type field
if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {
$fieldTransformer->setNoDefault(true);
}
return $this->item($field, $fieldTransformer);
}
return null;
}
}
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
21
1...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09740692,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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.8374335,"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":"TextRelayServiceTest","depth":6,"bounds":{"left":0.85272604,"top":0.019952115,"width":0.062832445,"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 'TextRelayServiceTest'","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 'TextRelayServiceTest'","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":"15","depth":4,"bounds":{"left":0.37632978,"top":0.12529927,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.3879654,"top":0.12529927,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39694148,"top":0.123703115,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40425533,"top":0.123703115,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutEntityTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'children',\n 'field',\n ];\n\n protected array $availableIncludes = [\n 'children',\n 'field',\n ];\n private $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n private bool $noDefaultActivityType = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n }\n\n public function setNoDefaultActivityType(bool $noDefaultActivityType)\n {\n $this->noDefaultActivityType = $noDefaultActivityType;\n }\n\n public function transform(LayoutEntity $entity): array\n {\n $label = $entity->getLabel();\n $description = $entity->description;\n $required = $entity->is_mandatory;\n\n // Inherit from the base field.\n $field = $entity->field;\n if ($field) {\n if ($label === null) {\n $label = $field->label;\n }\n\n if ($description === null && $field->description) {\n $description = $field->description;\n }\n\n if ($field->is_mandatory) {\n $required = true;\n }\n }\n\n return [\n 'id' => $entity->id_string,\n 'required' => $required,\n 'label' => $label,\n 'description' => $description,\n 'readOnly' => $entity->read_only,\n 'sequence' => $entity->sequence,\n ];\n }\n\n public function includeChildren(LayoutEntity $entity)\n {\n $children = $entity->children;\n if ($children) {\n $layoutEntityTransformer = new LayoutEntityTransformer($this->profile);\n\n // Check if transforming a Follow Up section\n if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {\n $layoutEntityTransformer->setNoDefaultActivityType(true);\n }\n\n return $this->collection($children, $layoutEntityTransformer);\n }\n\n return null;\n }\n\n public function includeField(LayoutEntity $entity)\n {\n $field = $entity->field;\n if ($field) {\n $fieldTransformer = new FieldTransformer($this->profile);\n\n // Check if transforming an Activity Type field\n if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {\n $fieldTransformer->setNoDefault(true);\n }\n\n return $this->item($field, $fieldTransformer);\n }\n\n return null;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutEntityTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'children',\n 'field',\n ];\n\n protected array $availableIncludes = [\n 'children',\n 'field',\n ];\n private $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n private bool $noDefaultActivityType = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n }\n\n public function setNoDefaultActivityType(bool $noDefaultActivityType)\n {\n $this->noDefaultActivityType = $noDefaultActivityType;\n }\n\n public function transform(LayoutEntity $entity): array\n {\n $label = $entity->getLabel();\n $description = $entity->description;\n $required = $entity->is_mandatory;\n\n // Inherit from the base field.\n $field = $entity->field;\n if ($field) {\n if ($label === null) {\n $label = $field->label;\n }\n\n if ($description === null && $field->description) {\n $description = $field->description;\n }\n\n if ($field->is_mandatory) {\n $required = true;\n }\n }\n\n return [\n 'id' => $entity->id_string,\n 'required' => $required,\n 'label' => $label,\n 'description' => $description,\n 'readOnly' => $entity->read_only,\n 'sequence' => $entity->sequence,\n ];\n }\n\n public function includeChildren(LayoutEntity $entity)\n {\n $children = $entity->children;\n if ($children) {\n $layoutEntityTransformer = new LayoutEntityTransformer($this->profile);\n\n // Check if transforming a Follow Up section\n if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {\n $layoutEntityTransformer->setNoDefaultActivityType(true);\n }\n\n return $this->collection($children, $layoutEntityTransformer);\n }\n\n return null;\n }\n\n public function includeField(LayoutEntity $entity)\n {\n $field = $entity->field;\n if ($field) {\n $fieldTransformer = new FieldTransformer($this->profile);\n\n // Check if transforming an Activity Type field\n if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {\n $fieldTransformer->setNoDefault(true);\n }\n\n return $this->item($field, $fieldTransformer);\n }\n\n return null;\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"bounds":{"left":0.41289893,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"bounds":{"left":0.42154256,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"bounds":{"left":0.4325133,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"bounds":{"left":0.44115692,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"bounds":{"left":0.44980052,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"bounds":{"left":0.46077126,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"bounds":{"left":0.47174203,"top":0.09896249,"width":0.024268618,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"bounds":{"left":0.49833778,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"bounds":{"left":0.5093085,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7237367,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"21","depth":4,"bounds":{"left":0.6868351,"top":0.123703115,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.6984708,"top":0.123703115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"}]...
|
3728857289934848669
|
4950805455163448201
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
15
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Crm\Profile;
use League\Fractal\TransformerAbstract;
class LayoutEntityTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'children',
'field',
];
protected array $availableIncludes = [
'children',
'field',
];
private $profile;
private bool $noDefaultActivityTypeFollowUp = false;
private bool $noDefaultActivityType = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
}
public function setNoDefaultActivityType(bool $noDefaultActivityType)
{
$this->noDefaultActivityType = $noDefaultActivityType;
}
public function transform(LayoutEntity $entity): array
{
$label = $entity->getLabel();
$description = $entity->description;
$required = $entity->is_mandatory;
// Inherit from the base field.
$field = $entity->field;
if ($field) {
if ($label === null) {
$label = $field->label;
}
if ($description === null && $field->description) {
$description = $field->description;
}
if ($field->is_mandatory) {
$required = true;
}
}
return [
'id' => $entity->id_string,
'required' => $required,
'label' => $label,
'description' => $description,
'readOnly' => $entity->read_only,
'sequence' => $entity->sequence,
];
}
public function includeChildren(LayoutEntity $entity)
{
$children = $entity->children;
if ($children) {
$layoutEntityTransformer = new LayoutEntityTransformer($this->profile);
// Check if transforming a Follow Up section
if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {
$layoutEntityTransformer->setNoDefaultActivityType(true);
}
return $this->collection($children, $layoutEntityTransformer);
}
return null;
}
public function includeField(LayoutEntity $entity)
{
$field = $entity->field;
if ($field) {
$fieldTransformer = new FieldTransformer($this->profile);
// Check if transforming an Activity Type field
if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {
$fieldTransformer->setNoDefault(true);
}
return $this->item($field, $fieldTransformer);
}
return null;
}
}
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
21
1...
|
79512
|
NULL
|
NULL
|
NULL
|
|
79513
|
2786
|
40
|
2026-05-28T06:32:50.299505+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949970299_m1.jpg...
|
PhpStorm
|
faVsco.js – LayoutEntityTransformer.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
15
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Crm\Profile;
use League\Fractal\TransformerAbstract;
class LayoutEntityTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'children',
'field',
];
protected array $availableIncludes = [
'children',
'field',
];
private $profile;
private bool $noDefaultActivityTypeFollowUp = false;
private bool $noDefaultActivityType = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
}
public function setNoDefaultActivityType(bool $noDefaultActivityType)
{
$this->noDefaultActivityType = $noDefaultActivityType;
}
public function transform(LayoutEntity $entity): array
{
$label = $entity->getLabel();
$description = $entity->description;
$required = $entity->is_mandatory;
// Inherit from the base field.
$field = $entity->field;
if ($field) {
if ($label === null) {
$label = $field->label;
}
if ($description === null && $field->description) {
$description = $field->description;
}
if ($field->is_mandatory) {
$required = true;
}
}
return [
'id' => $entity->id_string,
'required' => $required,
'label' => $label,
'description' => $description,
'readOnly' => $entity->read_only,
'sequence' => $entity->sequence,
];
}
public function includeChildren(LayoutEntity $entity)
{
$children = $entity->children;
if ($children) {
$layoutEntityTransformer = new LayoutEntityTransformer($this->profile);
// Check if transforming a Follow Up section
if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {
$layoutEntityTransformer->setNoDefaultActivityType(true);
}
return $this->collection($children, $layoutEntityTransformer);
}
return null;
}
public function includeField(LayoutEntity $entity)
{
$field = $entity->field;
if ($field) {
$fieldTransformer = new FieldTransformer($this->profile);
// Check if transforming an Activity Type field
if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {
$fieldTransformer->setNoDefault(true);
}
return $this->item($field, $fieldTransformer);
}
return null;
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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":"TextRelayServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'TextRelayServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'TextRelayServiceTest'","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":"15","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutEntityTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'children',\n 'field',\n ];\n\n protected array $availableIncludes = [\n 'children',\n 'field',\n ];\n private $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n private bool $noDefaultActivityType = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n }\n\n public function setNoDefaultActivityType(bool $noDefaultActivityType)\n {\n $this->noDefaultActivityType = $noDefaultActivityType;\n }\n\n public function transform(LayoutEntity $entity): array\n {\n $label = $entity->getLabel();\n $description = $entity->description;\n $required = $entity->is_mandatory;\n\n // Inherit from the base field.\n $field = $entity->field;\n if ($field) {\n if ($label === null) {\n $label = $field->label;\n }\n\n if ($description === null && $field->description) {\n $description = $field->description;\n }\n\n if ($field->is_mandatory) {\n $required = true;\n }\n }\n\n return [\n 'id' => $entity->id_string,\n 'required' => $required,\n 'label' => $label,\n 'description' => $description,\n 'readOnly' => $entity->read_only,\n 'sequence' => $entity->sequence,\n ];\n }\n\n public function includeChildren(LayoutEntity $entity)\n {\n $children = $entity->children;\n if ($children) {\n $layoutEntityTransformer = new LayoutEntityTransformer($this->profile);\n\n // Check if transforming a Follow Up section\n if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {\n $layoutEntityTransformer->setNoDefaultActivityType(true);\n }\n\n return $this->collection($children, $layoutEntityTransformer);\n }\n\n return null;\n }\n\n public function includeField(LayoutEntity $entity)\n {\n $field = $entity->field;\n if ($field) {\n $fieldTransformer = new FieldTransformer($this->profile);\n\n // Check if transforming an Activity Type field\n if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {\n $fieldTransformer->setNoDefault(true);\n }\n\n return $this->item($field, $fieldTransformer);\n }\n\n return null;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutEntityTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'children',\n 'field',\n ];\n\n protected array $availableIncludes = [\n 'children',\n 'field',\n ];\n private $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n private bool $noDefaultActivityType = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n }\n\n public function setNoDefaultActivityType(bool $noDefaultActivityType)\n {\n $this->noDefaultActivityType = $noDefaultActivityType;\n }\n\n public function transform(LayoutEntity $entity): array\n {\n $label = $entity->getLabel();\n $description = $entity->description;\n $required = $entity->is_mandatory;\n\n // Inherit from the base field.\n $field = $entity->field;\n if ($field) {\n if ($label === null) {\n $label = $field->label;\n }\n\n if ($description === null && $field->description) {\n $description = $field->description;\n }\n\n if ($field->is_mandatory) {\n $required = true;\n }\n }\n\n return [\n 'id' => $entity->id_string,\n 'required' => $required,\n 'label' => $label,\n 'description' => $description,\n 'readOnly' => $entity->read_only,\n 'sequence' => $entity->sequence,\n ];\n }\n\n public function includeChildren(LayoutEntity $entity)\n {\n $children = $entity->children;\n if ($children) {\n $layoutEntityTransformer = new LayoutEntityTransformer($this->profile);\n\n // Check if transforming a Follow Up section\n if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {\n $layoutEntityTransformer->setNoDefaultActivityType(true);\n }\n\n return $this->collection($children, $layoutEntityTransformer);\n }\n\n return null;\n }\n\n public function includeField(LayoutEntity $entity)\n {\n $field = $entity->field;\n if ($field) {\n $fieldTransformer = new FieldTransformer($this->profile);\n\n // Check if transforming an Activity Type field\n if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {\n $fieldTransformer->setNoDefault(true);\n }\n\n return $this->item($field, $fieldTransformer);\n }\n\n return null;\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-5302144940980817191
|
4950805455165545353
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
15
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Crm\Profile;
use League\Fractal\TransformerAbstract;
class LayoutEntityTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'children',
'field',
];
protected array $availableIncludes = [
'children',
'field',
];
private $profile;
private bool $noDefaultActivityTypeFollowUp = false;
private bool $noDefaultActivityType = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
}
public function setNoDefaultActivityType(bool $noDefaultActivityType)
{
$this->noDefaultActivityType = $noDefaultActivityType;
}
public function transform(LayoutEntity $entity): array
{
$label = $entity->getLabel();
$description = $entity->description;
$required = $entity->is_mandatory;
// Inherit from the base field.
$field = $entity->field;
if ($field) {
if ($label === null) {
$label = $field->label;
}
if ($description === null && $field->description) {
$description = $field->description;
}
if ($field->is_mandatory) {
$required = true;
}
}
return [
'id' => $entity->id_string,
'required' => $required,
'label' => $label,
'description' => $description,
'readOnly' => $entity->read_only,
'sequence' => $entity->sequence,
];
}
public function includeChildren(LayoutEntity $entity)
{
$children = $entity->children;
if ($children) {
$layoutEntityTransformer = new LayoutEntityTransformer($this->profile);
// Check if transforming a Follow Up section
if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {
$layoutEntityTransformer->setNoDefaultActivityType(true);
}
return $this->collection($children, $layoutEntityTransformer);
}
return null;
}
public function includeField(LayoutEntity $entity)
{
$field = $entity->field;
if ($field) {
$fieldTransformer = new FieldTransformer($this->profile);
// Check if transforming an Activity Type field
if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {
$fieldTransformer->setNoDefault(true);
}
return $this->item($field, $fieldTransformer);
}
return null;
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…...
|
79511
|
NULL
|
NULL
|
NULL
|
|
79512
|
2787
|
64
|
2026-05-28T06:32:45.241271+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949965241_m2.jpg...
|
PhpStorm
|
faVsco.js – LayoutEntityTransformer.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
15
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Crm\Profile;
use League\Fractal\TransformerAbstract;
class LayoutEntityTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'children',
'field',
];
protected array $availableIncludes = [
'children',
'field',
];
private $profile;
private bool $noDefaultActivityTypeFollowUp = false;
private bool $noDefaultActivityType = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
}
public function setNoDefaultActivityType(bool $noDefaultActivityType)
{
$this->noDefaultActivityType = $noDefaultActivityType;
}
public function transform(LayoutEntity $entity): array
{
$label = $entity->getLabel();
$description = $entity->description;
$required = $entity->is_mandatory;
// Inherit from the base field.
$field = $entity->field;
if ($field) {
if ($label === null) {
$label = $field->label;
}
if ($description === null && $field->description) {
$description = $field->description;
}
if ($field->is_mandatory) {
$required = true;
}
}
return [
'id' => $entity->id_string,
'required' => $required,
'label' => $label,
'description' => $description,
'readOnly' => $entity->read_only,
'sequence' => $entity->sequence,
];
}
public function includeChildren(LayoutEntity $entity)
{
$children = $entity->children;
if ($children) {
$layoutEntityTransformer = new LayoutEntityTransformer($this->profile);
// Check if transforming a Follow Up section
if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {
$layoutEntityTransformer->setNoDefaultActivityType(true);
}
return $this->collection($children, $layoutEntityTransformer);
}
return null;
}
public function includeField(LayoutEntity $entity)
{
$field = $entity->field;
if ($field) {
$fieldTransformer = new FieldTransformer($this->profile);
// Check if transforming an Activity Type field
if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {
$fieldTransformer->setNoDefault(true);
}
return $this->item($field, $fieldTransformer);
}
return null;
}
}...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09740692,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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.8374335,"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":"TextRelayServiceTest","depth":6,"bounds":{"left":0.85272604,"top":0.019952115,"width":0.062832445,"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 'TextRelayServiceTest'","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 'TextRelayServiceTest'","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":"15","depth":4,"bounds":{"left":0.37632978,"top":0.12529927,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.3879654,"top":0.12529927,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39694148,"top":0.123703115,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40425533,"top":0.123703115,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutEntityTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'children',\n 'field',\n ];\n\n protected array $availableIncludes = [\n 'children',\n 'field',\n ];\n private $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n private bool $noDefaultActivityType = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n }\n\n public function setNoDefaultActivityType(bool $noDefaultActivityType)\n {\n $this->noDefaultActivityType = $noDefaultActivityType;\n }\n\n public function transform(LayoutEntity $entity): array\n {\n $label = $entity->getLabel();\n $description = $entity->description;\n $required = $entity->is_mandatory;\n\n // Inherit from the base field.\n $field = $entity->field;\n if ($field) {\n if ($label === null) {\n $label = $field->label;\n }\n\n if ($description === null && $field->description) {\n $description = $field->description;\n }\n\n if ($field->is_mandatory) {\n $required = true;\n }\n }\n\n return [\n 'id' => $entity->id_string,\n 'required' => $required,\n 'label' => $label,\n 'description' => $description,\n 'readOnly' => $entity->read_only,\n 'sequence' => $entity->sequence,\n ];\n }\n\n public function includeChildren(LayoutEntity $entity)\n {\n $children = $entity->children;\n if ($children) {\n $layoutEntityTransformer = new LayoutEntityTransformer($this->profile);\n\n // Check if transforming a Follow Up section\n if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {\n $layoutEntityTransformer->setNoDefaultActivityType(true);\n }\n\n return $this->collection($children, $layoutEntityTransformer);\n }\n\n return null;\n }\n\n public function includeField(LayoutEntity $entity)\n {\n $field = $entity->field;\n if ($field) {\n $fieldTransformer = new FieldTransformer($this->profile);\n\n // Check if transforming an Activity Type field\n if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {\n $fieldTransformer->setNoDefault(true);\n }\n\n return $this->item($field, $fieldTransformer);\n }\n\n return null;\n }\n}","depth":4,"bounds":{"left":0.13630319,"top":0.12051077,"width":0.27493352,"height":0.87948924},"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutEntityTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'children',\n 'field',\n ];\n\n protected array $availableIncludes = [\n 'children',\n 'field',\n ];\n private $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n private bool $noDefaultActivityType = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n }\n\n public function setNoDefaultActivityType(bool $noDefaultActivityType)\n {\n $this->noDefaultActivityType = $noDefaultActivityType;\n }\n\n public function transform(LayoutEntity $entity): array\n {\n $label = $entity->getLabel();\n $description = $entity->description;\n $required = $entity->is_mandatory;\n\n // Inherit from the base field.\n $field = $entity->field;\n if ($field) {\n if ($label === null) {\n $label = $field->label;\n }\n\n if ($description === null && $field->description) {\n $description = $field->description;\n }\n\n if ($field->is_mandatory) {\n $required = true;\n }\n }\n\n return [\n 'id' => $entity->id_string,\n 'required' => $required,\n 'label' => $label,\n 'description' => $description,\n 'readOnly' => $entity->read_only,\n 'sequence' => $entity->sequence,\n ];\n }\n\n public function includeChildren(LayoutEntity $entity)\n {\n $children = $entity->children;\n if ($children) {\n $layoutEntityTransformer = new LayoutEntityTransformer($this->profile);\n\n // Check if transforming a Follow Up section\n if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {\n $layoutEntityTransformer->setNoDefaultActivityType(true);\n }\n\n return $this->collection($children, $layoutEntityTransformer);\n }\n\n return null;\n }\n\n public function includeField(LayoutEntity $entity)\n {\n $field = $entity->field;\n if ($field) {\n $fieldTransformer = new FieldTransformer($this->profile);\n\n // Check if transforming an Activity Type field\n if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {\n $fieldTransformer->setNoDefault(true);\n }\n\n return $this->item($field, $fieldTransformer);\n }\n\n return null;\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false}]...
|
-8025676060474955499
|
4946301854699314073
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
15
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Crm\Profile;
use League\Fractal\TransformerAbstract;
class LayoutEntityTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'children',
'field',
];
protected array $availableIncludes = [
'children',
'field',
];
private $profile;
private bool $noDefaultActivityTypeFollowUp = false;
private bool $noDefaultActivityType = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
}
public function setNoDefaultActivityType(bool $noDefaultActivityType)
{
$this->noDefaultActivityType = $noDefaultActivityType;
}
public function transform(LayoutEntity $entity): array
{
$label = $entity->getLabel();
$description = $entity->description;
$required = $entity->is_mandatory;
// Inherit from the base field.
$field = $entity->field;
if ($field) {
if ($label === null) {
$label = $field->label;
}
if ($description === null && $field->description) {
$description = $field->description;
}
if ($field->is_mandatory) {
$required = true;
}
}
return [
'id' => $entity->id_string,
'required' => $required,
'label' => $label,
'description' => $description,
'readOnly' => $entity->read_only,
'sequence' => $entity->sequence,
];
}
public function includeChildren(LayoutEntity $entity)
{
$children = $entity->children;
if ($children) {
$layoutEntityTransformer = new LayoutEntityTransformer($this->profile);
// Check if transforming a Follow Up section
if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {
$layoutEntityTransformer->setNoDefaultActivityType(true);
}
return $this->collection($children, $layoutEntityTransformer);
}
return null;
}
public function includeField(LayoutEntity $entity)
{
$field = $entity->field;
if ($field) {
$fieldTransformer = new FieldTransformer($this->profile);
// Check if transforming an Activity Type field
if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {
$fieldTransformer->setNoDefault(true);
}
return $this->item($field, $fieldTransformer);
}
return null;
}
}...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79511
|
2786
|
39
|
2026-05-28T06:32:45.118954+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949965118_m1.jpg...
|
PhpStorm
|
faVsco.js – LayoutEntityTransformer.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
15
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Crm\Profile;
use League\Fractal\TransformerAbstract;
class LayoutEntityTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'children',
'field',
];
protected array $availableIncludes = [
'children',
'field',
];
private $profile;
private bool $noDefaultActivityTypeFollowUp = false;
private bool $noDefaultActivityType = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
}
public function setNoDefaultActivityType(bool $noDefaultActivityType)
{
$this->noDefaultActivityType = $noDefaultActivityType;
}
public function transform(LayoutEntity $entity): array
{
$label = $entity->getLabel();
$description = $entity->description;
$required = $entity->is_mandatory;
// Inherit from the base field.
$field = $entity->field;
if ($field) {
if ($label === null) {
$label = $field->label;
}
if ($description === null && $field->description) {
$description = $field->description;
}
if ($field->is_mandatory) {
$required = true;
}
}
return [
'id' => $entity->id_string,
'required' => $required,
'label' => $label,
'description' => $description,
'readOnly' => $entity->read_only,
'sequence' => $entity->sequence,
];
}
public function includeChildren(LayoutEntity $entity)
{
$children = $entity->children;
if ($children) {
$layoutEntityTransformer = new LayoutEntityTransformer($this->profile);
// Check if transforming a Follow Up section
if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {
$layoutEntityTransformer->setNoDefaultActivityType(true);
}
return $this->collection($children, $layoutEntityTransformer);
}
return null;
}
public function includeField(LayoutEntity $entity)
{
$field = $entity->field;
if ($field) {
$fieldTransformer = new FieldTransformer($this->profile);
// Check if transforming an Activity Type field
if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {
$fieldTransformer->setNoDefault(true);
}
return $this->item($field, $fieldTransformer);
}
return null;
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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":"TextRelayServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'TextRelayServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'TextRelayServiceTest'","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":"15","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutEntityTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'children',\n 'field',\n ];\n\n protected array $availableIncludes = [\n 'children',\n 'field',\n ];\n private $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n private bool $noDefaultActivityType = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n }\n\n public function setNoDefaultActivityType(bool $noDefaultActivityType)\n {\n $this->noDefaultActivityType = $noDefaultActivityType;\n }\n\n public function transform(LayoutEntity $entity): array\n {\n $label = $entity->getLabel();\n $description = $entity->description;\n $required = $entity->is_mandatory;\n\n // Inherit from the base field.\n $field = $entity->field;\n if ($field) {\n if ($label === null) {\n $label = $field->label;\n }\n\n if ($description === null && $field->description) {\n $description = $field->description;\n }\n\n if ($field->is_mandatory) {\n $required = true;\n }\n }\n\n return [\n 'id' => $entity->id_string,\n 'required' => $required,\n 'label' => $label,\n 'description' => $description,\n 'readOnly' => $entity->read_only,\n 'sequence' => $entity->sequence,\n ];\n }\n\n public function includeChildren(LayoutEntity $entity)\n {\n $children = $entity->children;\n if ($children) {\n $layoutEntityTransformer = new LayoutEntityTransformer($this->profile);\n\n // Check if transforming a Follow Up section\n if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {\n $layoutEntityTransformer->setNoDefaultActivityType(true);\n }\n\n return $this->collection($children, $layoutEntityTransformer);\n }\n\n return null;\n }\n\n public function includeField(LayoutEntity $entity)\n {\n $field = $entity->field;\n if ($field) {\n $fieldTransformer = new FieldTransformer($this->profile);\n\n // Check if transforming an Activity Type field\n if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {\n $fieldTransformer->setNoDefault(true);\n }\n\n return $this->item($field, $fieldTransformer);\n }\n\n return null;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutEntityTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'children',\n 'field',\n ];\n\n protected array $availableIncludes = [\n 'children',\n 'field',\n ];\n private $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n private bool $noDefaultActivityType = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n }\n\n public function setNoDefaultActivityType(bool $noDefaultActivityType)\n {\n $this->noDefaultActivityType = $noDefaultActivityType;\n }\n\n public function transform(LayoutEntity $entity): array\n {\n $label = $entity->getLabel();\n $description = $entity->description;\n $required = $entity->is_mandatory;\n\n // Inherit from the base field.\n $field = $entity->field;\n if ($field) {\n if ($label === null) {\n $label = $field->label;\n }\n\n if ($description === null && $field->description) {\n $description = $field->description;\n }\n\n if ($field->is_mandatory) {\n $required = true;\n }\n }\n\n return [\n 'id' => $entity->id_string,\n 'required' => $required,\n 'label' => $label,\n 'description' => $description,\n 'readOnly' => $entity->read_only,\n 'sequence' => $entity->sequence,\n ];\n }\n\n public function includeChildren(LayoutEntity $entity)\n {\n $children = $entity->children;\n if ($children) {\n $layoutEntityTransformer = new LayoutEntityTransformer($this->profile);\n\n // Check if transforming a Follow Up section\n if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {\n $layoutEntityTransformer->setNoDefaultActivityType(true);\n }\n\n return $this->collection($children, $layoutEntityTransformer);\n }\n\n return null;\n }\n\n public function includeField(LayoutEntity $entity)\n {\n $field = $entity->field;\n if ($field) {\n $fieldTransformer = new FieldTransformer($this->profile);\n\n // Check if transforming an Activity Type field\n if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {\n $fieldTransformer->setNoDefault(true);\n }\n\n return $this->item($field, $fieldTransformer);\n }\n\n return null;\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-158098104852428941
|
4950805454895012761
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
15
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Crm\Profile;
use League\Fractal\TransformerAbstract;
class LayoutEntityTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'children',
'field',
];
protected array $availableIncludes = [
'children',
'field',
];
private $profile;
private bool $noDefaultActivityTypeFollowUp = false;
private bool $noDefaultActivityType = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp)
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
}
public function setNoDefaultActivityType(bool $noDefaultActivityType)
{
$this->noDefaultActivityType = $noDefaultActivityType;
}
public function transform(LayoutEntity $entity): array
{
$label = $entity->getLabel();
$description = $entity->description;
$required = $entity->is_mandatory;
// Inherit from the base field.
$field = $entity->field;
if ($field) {
if ($label === null) {
$label = $field->label;
}
if ($description === null && $field->description) {
$description = $field->description;
}
if ($field->is_mandatory) {
$required = true;
}
}
return [
'id' => $entity->id_string,
'required' => $required,
'label' => $label,
'description' => $description,
'readOnly' => $entity->read_only,
'sequence' => $entity->sequence,
];
}
public function includeChildren(LayoutEntity $entity)
{
$children = $entity->children;
if ($children) {
$layoutEntityTransformer = new LayoutEntityTransformer($this->profile);
// Check if transforming a Follow Up section
if ($this->noDefaultActivityTypeFollowUp && $entity->label === 'follow-up') {
$layoutEntityTransformer->setNoDefaultActivityType(true);
}
return $this->collection($children, $layoutEntityTransformer);
}
return null;
}
public function includeField(LayoutEntity $entity)
{
$field = $entity->field;
if ($field) {
$fieldTransformer = new FieldTransformer($this->profile);
// Check if transforming an Activity Type field
if ($this->noDefaultActivityType && $field->crm_provider_id === 'Type') {
$fieldTransformer->setNoDefault(true);
}
return $this->item($field, $fieldTransformer);
}
return null;
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79510
|
2786
|
38
|
2026-05-28T06:32:40.240245+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949960240_m1.jpg...
|
PhpStorm
|
faVsco.js – LayoutTransformer.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
7
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\Profile;
use League\Fractal\Resource\Collection as FractalResourceCollection;
use League\Fractal\TransformerAbstract;
class LayoutTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'entities',
];
protected array $availableIncludes = [
'entities',
];
private ?Profile $profile;
private bool $noDefaultActivityTypeFollowUp = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
/**
* A Fractal transformer.
*/
public function transform(Layout $layout): array
{
return [
'id' => $layout->id_string,
'type' => $layout->type,
];
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp): self
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
return $this;
}
/**
* Include Entities.
*/
public function includeEntities(Layout $layout): FractalResourceCollection
{
// Get all top-level sections and their nested fields.
$entities = $layout->entities()
->whereNull('parent_entity_id')
->with(['children', 'field.values'])
->orderBy('sequence');
$transformer = new LayoutEntityTransformer($this->profile);
$transformer->setNoDefaultActivityTypeFollowUp($this->noDefaultActivityTypeFollowUp);
return $this->collection($entities->get(), $transformer);
}
}
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
21
1
18
2
6
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id
where u.team_id = 1;
SELECT * FROM social_accounts WHERE sociable_id = 1635;
SELECT * FROM users WHERE id = 1635;
select * from teams where id = 1;
select * from users where team_id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role;
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
SELECT * FROM automated_reports where id = 71;
SELECT * FROM automated_report_results where report_id = 71;
UPDATE automated_reports set playbook_categories = NULL where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT `automated_report_results`.* FROM `automated_report_results`
INNER JOIN `automated_reports`
ON `automated_report_results`.`report_id` = `automated_reports`.`id`
WHERE 1=1
AND `automated_report_results`.`generated_at` IS NOT NULL
# AND `automated_report_results`.`sent_at` IS NOT NULL
AND `automated_reports`.`team_id` = 1
AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$."users"')
;
SELECT * FROM automated_reports where id = 67;
SELECT * FROM automated_reports where id = 42;
SELECT * FROM users WHERE id = 143; # group 28
select * from teams where id = 3143;
select * from crm_configurations where id = 500;
select * from users where name = 'Integration Account'; # 1695
SELECT * FROM social_accounts WHERE sociable_id = 1695;
select * from activities where crm_configuration_id = 39
and recording_state = 'recorded' and duration > 60
and status = 'completed' and actual_start_time >= '2025-12-01';
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;
select * from leads;
SELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003
SELECT * FROM activities WHERE id IN (16,422003);
SELECT * FROM activities where status = 'failed';
SELECT * FROM tracks WHERE activity_id = 422003;
SELECT
a.*
FROM activities a
JOIN users u ON a.user_id = u.id
WHERE
a.status = 'completed'
AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid
AND a.deleted_at IS NULL
AND EXISTS (
SELECT 1 FROM tracks t
WHERE t.activity_id = a.id
AND t.type IN ('audio', 'video')
)
ORDER BY a.actual_start_time DESC
LIMIT 25;
select * from teams where id = 19;
select * from crm_configurations where provider = 'pipedrive';
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 = 19 and sa.provider = 'pipedrive';
SELECT * FROM social_accounts WHERE id = 1116;
UPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',
provider_refresh_token = '5034113:[TELEGRAM_TOKEN]b2bfc',
expires = 1779091997,
state = 'connected'
WHERE id = 1116;
"provider_user_token": "v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA",
"provider_refresh_token": "5034113:[TELEGRAM_TOKEN]b2bfc",
"expires": 1779091997,
select * from crm_field_values;
select * from crm_fields where type = 'multi-picklist';
SELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
SELECT * FROM crm_fields WHERE id = 3014; # 1885
SELECT * FROM crm_field_values WHERE crm_field_id = 3014;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20915-fix-missing-header-text-relay, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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":"TextRelayServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'TextRelayServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'TextRelayServiceTest'","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":"7","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\Resource\\Collection as FractalResourceCollection;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'entities',\n ];\n\n protected array $availableIncludes = [\n 'entities',\n ];\n private ?Profile $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n /**\n * A Fractal transformer.\n */\n public function transform(Layout $layout): array\n {\n return [\n 'id' => $layout->id_string,\n 'type' => $layout->type,\n ];\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp): self\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n\n return $this;\n }\n\n /**\n * Include Entities.\n */\n public function includeEntities(Layout $layout): FractalResourceCollection\n {\n // Get all top-level sections and their nested fields.\n $entities = $layout->entities()\n ->whereNull('parent_entity_id')\n ->with(['children', 'field.values'])\n ->orderBy('sequence');\n\n $transformer = new LayoutEntityTransformer($this->profile);\n $transformer->setNoDefaultActivityTypeFollowUp($this->noDefaultActivityTypeFollowUp);\n\n return $this->collection($entities->get(), $transformer);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\Resource\\Collection as FractalResourceCollection;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'entities',\n ];\n\n protected array $availableIncludes = [\n 'entities',\n ];\n private ?Profile $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n /**\n * A Fractal transformer.\n */\n public function transform(Layout $layout): array\n {\n return [\n 'id' => $layout->id_string,\n 'type' => $layout->type,\n ];\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp): self\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n\n return $this;\n }\n\n /**\n * Include Entities.\n */\n public function includeEntities(Layout $layout): FractalResourceCollection\n {\n // Get all top-level sections and their nested fields.\n $entities = $layout->entities()\n ->whereNull('parent_entity_id')\n ->with(['children', 'field.values'])\n ->orderBy('sequence');\n\n $transformer = new LayoutEntityTransformer($this->profile);\n $transformer->setNoDefaultActivityTypeFollowUp($this->noDefaultActivityTypeFollowUp);\n\n return $this->collection($entities->get(), $transformer);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"21","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"18","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"6","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\n\nselect sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id\nwhere u.team_id = 1;\nSELECT * FROM social_accounts WHERE sociable_id = 1635;\nSELECT * FROM users WHERE id = 1635;\n\nselect * from teams where id = 1;\nselect * from users where team_id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role;\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\nSELECT * FROM automated_reports where id = 71;\nSELECT * FROM automated_report_results where report_id = 71;\nUPDATE automated_reports set playbook_categories = NULL where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT `automated_report_results`.* FROM `automated_report_results`\nINNER JOIN `automated_reports`\n ON `automated_report_results`.`report_id` = `automated_reports`.`id`\nWHERE 1=1\n AND `automated_report_results`.`generated_at` IS NOT NULL\n# AND `automated_report_results`.`sent_at` IS NOT NULL\n AND `automated_reports`.`team_id` = 1\n AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$.\"users\"')\n;\n\nSELECT * FROM automated_reports where id = 67;\nSELECT * FROM automated_reports where id = 42;\nSELECT * FROM users WHERE id = 143; # group 28\n\nselect * from teams where id = 3143;\nselect * from crm_configurations where id = 500;\nselect * from users where name = 'Integration Account'; # 1695\nSELECT * FROM social_accounts WHERE sociable_id = 1695;\n\nselect * from activities where crm_configuration_id = 39\nand recording_state = 'recorded' and duration > 60\nand status = 'completed' and actual_start_time >= '2025-12-01';\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;\n\nselect * from leads;\n\nSELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003\nSELECT * FROM activities WHERE id IN (16,422003);\nSELECT * FROM activities where status = 'failed';\n\nSELECT * FROM tracks WHERE activity_id = 422003;\n\nSELECT\n a.*\nFROM activities a\nJOIN users u ON a.user_id = u.id\nWHERE\n a.status = 'completed'\n AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid\n AND a.deleted_at IS NULL\n AND EXISTS (\n SELECT 1 FROM tracks t\n WHERE t.activity_id = a.id\n AND t.type IN ('audio', 'video')\n )\nORDER BY a.actual_start_time DESC\nLIMIT 25;\n\nselect * from teams where id = 19;\nselect * from crm_configurations where provider = 'pipedrive';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 19 and sa.provider = 'pipedrive';\n\nSELECT * FROM social_accounts WHERE id = 1116;\n\nUPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',\nprovider_refresh_token = '5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc',\nexpires = 1779091997,\nstate = 'connected'\nWHERE id = 1116;\n\n \"provider_user_token\": \"v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA\",\n \"provider_refresh_token\": \"5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc\",\n \"expires\": 1779091997,\n\nselect * from crm_field_values;\n\nselect * from crm_fields where type = 'multi-picklist';\nSELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\nSELECT * FROM crm_fields WHERE id = 3014; # 1885\nSELECT * FROM crm_field_values WHERE crm_field_id = 3014;","depth":4,"on_screen":true,"value":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\n\nselect sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id\nwhere u.team_id = 1;\nSELECT * FROM social_accounts WHERE sociable_id = 1635;\nSELECT * FROM users WHERE id = 1635;\n\nselect * from teams where id = 1;\nselect * from users where team_id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role;\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\nSELECT * FROM automated_reports where id = 71;\nSELECT * FROM automated_report_results where report_id = 71;\nUPDATE automated_reports set playbook_categories = NULL where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT `automated_report_results`.* FROM `automated_report_results`\nINNER JOIN `automated_reports`\n ON `automated_report_results`.`report_id` = `automated_reports`.`id`\nWHERE 1=1\n AND `automated_report_results`.`generated_at` IS NOT NULL\n# AND `automated_report_results`.`sent_at` IS NOT NULL\n AND `automated_reports`.`team_id` = 1\n AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$.\"users\"')\n;\n\nSELECT * FROM automated_reports where id = 67;\nSELECT * FROM automated_reports where id = 42;\nSELECT * FROM users WHERE id = 143; # group 28\n\nselect * from teams where id = 3143;\nselect * from crm_configurations where id = 500;\nselect * from users where name = 'Integration Account'; # 1695\nSELECT * FROM social_accounts WHERE sociable_id = 1695;\n\nselect * from activities where crm_configuration_id = 39\nand recording_state = 'recorded' and duration > 60\nand status = 'completed' and actual_start_time >= '2025-12-01';\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;\n\nselect * from leads;\n\nSELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003\nSELECT * FROM activities WHERE id IN (16,422003);\nSELECT * FROM activities where status = 'failed';\n\nSELECT * FROM tracks WHERE activity_id = 422003;\n\nSELECT\n a.*\nFROM activities a\nJOIN users u ON a.user_id = u.id\nWHERE\n a.status = 'completed'\n AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid\n AND a.deleted_at IS NULL\n AND EXISTS (\n SELECT 1 FROM tracks t\n WHERE t.activity_id = a.id\n AND t.type IN ('audio', 'video')\n )\nORDER BY a.actual_start_time DESC\nLIMIT 25;\n\nselect * from teams where id = 19;\nselect * from crm_configurations where provider = 'pipedrive';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 19 and sa.provider = 'pipedrive';\n\nSELECT * FROM social_accounts WHERE id = 1116;\n\nUPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',\nprovider_refresh_token = '5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc',\nexpires = 1779091997,\nstate = 'connected'\nWHERE id = 1116;\n\n \"provider_user_token\": \"v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA\",\n \"provider_refresh_token\": \"5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc\",\n \"expires\": 1779091997,\n\nselect * from crm_field_values;\n\nselect * from crm_fields where type = 'multi-picklist';\nSELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\nSELECT * FROM crm_fields WHERE id = 3014; # 1885\nSELECT * FROM crm_field_values WHERE crm_field_id = 3014;","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}]...
|
4594891295601732351
|
6830303738765645389
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
7
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\Profile;
use League\Fractal\Resource\Collection as FractalResourceCollection;
use League\Fractal\TransformerAbstract;
class LayoutTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'entities',
];
protected array $availableIncludes = [
'entities',
];
private ?Profile $profile;
private bool $noDefaultActivityTypeFollowUp = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
/**
* A Fractal transformer.
*/
public function transform(Layout $layout): array
{
return [
'id' => $layout->id_string,
'type' => $layout->type,
];
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp): self
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
return $this;
}
/**
* Include Entities.
*/
public function includeEntities(Layout $layout): FractalResourceCollection
{
// Get all top-level sections and their nested fields.
$entities = $layout->entities()
->whereNull('parent_entity_id')
->with(['children', 'field.values'])
->orderBy('sequence');
$transformer = new LayoutEntityTransformer($this->profile);
$transformer->setNoDefaultActivityTypeFollowUp($this->noDefaultActivityTypeFollowUp);
return $this->collection($entities->get(), $transformer);
}
}
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
21
1
18
2
6
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id
where u.team_id = 1;
SELECT * FROM social_accounts WHERE sociable_id = 1635;
SELECT * FROM users WHERE id = 1635;
select * from teams where id = 1;
select * from users where team_id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role;
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
SELECT * FROM automated_reports where id = 71;
SELECT * FROM automated_report_results where report_id = 71;
UPDATE automated_reports set playbook_categories = NULL where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT `automated_report_results`.* FROM `automated_report_results`
INNER JOIN `automated_reports`
ON `automated_report_results`.`report_id` = `automated_reports`.`id`
WHERE 1=1
AND `automated_report_results`.`generated_at` IS NOT NULL
# AND `automated_report_results`.`sent_at` IS NOT NULL
AND `automated_reports`.`team_id` = 1
AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$."users"')
;
SELECT * FROM automated_reports where id = 67;
SELECT * FROM automated_reports where id = 42;
SELECT * FROM users WHERE id = 143; # group 28
select * from teams where id = 3143;
select * from crm_configurations where id = 500;
select * from users where name = 'Integration Account'; # 1695
SELECT * FROM social_accounts WHERE sociable_id = 1695;
select * from activities where crm_configuration_id = 39
and recording_state = 'recorded' and duration > 60
and status = 'completed' and actual_start_time >= '2025-12-01';
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;
select * from leads;
SELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003
SELECT * FROM activities WHERE id IN (16,422003);
SELECT * FROM activities where status = 'failed';
SELECT * FROM tracks WHERE activity_id = 422003;
SELECT
a.*
FROM activities a
JOIN users u ON a.user_id = u.id
WHERE
a.status = 'completed'
AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid
AND a.deleted_at IS NULL
AND EXISTS (
SELECT 1 FROM tracks t
WHERE t.activity_id = a.id
AND t.type IN ('audio', 'video')
)
ORDER BY a.actual_start_time DESC
LIMIT 25;
select * from teams where id = 19;
select * from crm_configurations where provider = 'pipedrive';
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 = 19 and sa.provider = 'pipedrive';
SELECT * FROM social_accounts WHERE id = 1116;
UPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',
provider_refresh_token = '5034113:[TELEGRAM_TOKEN]b2bfc',
expires = 1779091997,
state = 'connected'
WHERE id = 1116;
"provider_user_token": "v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA",
"provider_refresh_token": "5034113:[TELEGRAM_TOKEN]b2bfc",
"expires": 1779091997,
select * from crm_field_values;
select * from crm_fields where type = 'multi-picklist';
SELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
SELECT * FROM crm_fields WHERE id = 3014; # 1885
SELECT * FROM crm_field_values WHERE crm_field_id = 3014;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
79508
|
NULL
|
NULL
|
NULL
|
|
79509
|
2787
|
63
|
2026-05-28T06:32:40.135705+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949960135_m2.jpg...
|
PhpStorm
|
faVsco.js – LayoutTransformer.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
7
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\Profile;
use League\Fractal\Resource\Collection as FractalResourceCollection;
use League\Fractal\TransformerAbstract;
class LayoutTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'entities',
];
protected array $availableIncludes = [
'entities',
];
private ?Profile $profile;
private bool $noDefaultActivityTypeFollowUp = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
/**
* A Fractal transformer.
*/
public function transform(Layout $layout): array
{
return [
'id' => $layout->id_string,
'type' => $layout->type,
];
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp): self
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
return $this;
}
/**
* Include Entities.
*/
public function includeEntities(Layout $layout): FractalResourceCollection
{
// Get all top-level sections and their nested fields.
$entities = $layout->entities()
->whereNull('parent_entity_id')
->with(['children', 'field.values'])
->orderBy('sequence');
$transformer = new LayoutEntityTransformer($this->profile);
$transformer->setNoDefaultActivityTypeFollowUp($this->noDefaultActivityTypeFollowUp);
return $this->collection($entities->get(), $transformer);
}
}...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09740692,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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.8374335,"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":"TextRelayServiceTest","depth":6,"bounds":{"left":0.85272604,"top":0.019952115,"width":0.062832445,"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 'TextRelayServiceTest'","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 'TextRelayServiceTest'","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":"7","depth":4,"bounds":{"left":0.38763297,"top":0.12529927,"width":0.0076462766,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39694148,"top":0.123703115,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40425533,"top":0.123703115,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\Resource\\Collection as FractalResourceCollection;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'entities',\n ];\n\n protected array $availableIncludes = [\n 'entities',\n ];\n private ?Profile $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n /**\n * A Fractal transformer.\n */\n public function transform(Layout $layout): array\n {\n return [\n 'id' => $layout->id_string,\n 'type' => $layout->type,\n ];\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp): self\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n\n return $this;\n }\n\n /**\n * Include Entities.\n */\n public function includeEntities(Layout $layout): FractalResourceCollection\n {\n // Get all top-level sections and their nested fields.\n $entities = $layout->entities()\n ->whereNull('parent_entity_id')\n ->with(['children', 'field.values'])\n ->orderBy('sequence');\n\n $transformer = new LayoutEntityTransformer($this->profile);\n $transformer->setNoDefaultActivityTypeFollowUp($this->noDefaultActivityTypeFollowUp);\n\n return $this->collection($entities->get(), $transformer);\n }\n}","depth":4,"bounds":{"left":0.13364361,"top":0.12210695,"width":0.27759308,"height":0.87789303},"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\Resource\\Collection as FractalResourceCollection;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'entities',\n ];\n\n protected array $availableIncludes = [\n 'entities',\n ];\n private ?Profile $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n /**\n * A Fractal transformer.\n */\n public function transform(Layout $layout): array\n {\n return [\n 'id' => $layout->id_string,\n 'type' => $layout->type,\n ];\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp): self\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n\n return $this;\n }\n\n /**\n * Include Entities.\n */\n public function includeEntities(Layout $layout): FractalResourceCollection\n {\n // Get all top-level sections and their nested fields.\n $entities = $layout->entities()\n ->whereNull('parent_entity_id')\n ->with(['children', 'field.values'])\n ->orderBy('sequence');\n\n $transformer = new LayoutEntityTransformer($this->profile);\n $transformer->setNoDefaultActivityTypeFollowUp($this->noDefaultActivityTypeFollowUp);\n\n return $this->collection($entities->get(), $transformer);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false}]...
|
7846431260043059407
|
6247736628687749621
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
7
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\Profile;
use League\Fractal\Resource\Collection as FractalResourceCollection;
use League\Fractal\TransformerAbstract;
class LayoutTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'entities',
];
protected array $availableIncludes = [
'entities',
];
private ?Profile $profile;
private bool $noDefaultActivityTypeFollowUp = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
/**
* A Fractal transformer.
*/
public function transform(Layout $layout): array
{
return [
'id' => $layout->id_string,
'type' => $layout->type,
];
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp): self
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
return $this;
}
/**
* Include Entities.
*/
public function includeEntities(Layout $layout): FractalResourceCollection
{
// Get all top-level sections and their nested fields.
$entities = $layout->entities()
->whereNull('parent_entity_id')
->with(['children', 'field.values'])
->orderBy('sequence');
$transformer = new LayoutEntityTransformer($this->profile);
$transformer->setNoDefaultActivityTypeFollowUp($this->noDefaultActivityTypeFollowUp);
return $this->collection($entities->get(), $transformer);
}
}...
|
79507
|
NULL
|
NULL
|
NULL
|
|
79507
|
2787
|
62
|
2026-05-28T06:32:39.067054+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949959067_m2.jpg...
|
PhpStorm
|
faVsco.js – LayoutTransformer.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
7
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\Profile;
use League\Fractal\Resource\Collection as FractalResourceCollection;
use League\Fractal\TransformerAbstract;
class LayoutTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'entities',
];
protected array $availableIncludes = [
'entities',
];
private ?Profile $profile;
private bool $noDefaultActivityTypeFollowUp = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
/**
* A Fractal transformer.
*/
public function transform(Layout $layout): array
{
return [
'id' => $layout->id_string,
'type' => $layout->type,
];
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp): self
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
return $this;
}
/**
* Include Entities.
*/
public function includeEntities(Layout $layout): FractalResourceCollection
{
// Get all top-level sections and their nested fields.
$entities = $layout->entities()
->whereNull('parent_entity_id')
->with(['children', 'field.values'])
->orderBy('sequence');
$transformer = new LayoutEntityTransformer($this->profile);
$transformer->setNoDefaultActivityTypeFollowUp($this->noDefaultActivityTypeFollowUp);
return $this->collection($entities->get(), $transformer);
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09740692,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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.8374335,"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":"TextRelayServiceTest","depth":6,"bounds":{"left":0.85272604,"top":0.019952115,"width":0.062832445,"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 'TextRelayServiceTest'","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 'TextRelayServiceTest'","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":"7","depth":4,"bounds":{"left":0.38763297,"top":0.12529927,"width":0.0076462766,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39694148,"top":0.123703115,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40425533,"top":0.123703115,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\Resource\\Collection as FractalResourceCollection;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'entities',\n ];\n\n protected array $availableIncludes = [\n 'entities',\n ];\n private ?Profile $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n /**\n * A Fractal transformer.\n */\n public function transform(Layout $layout): array\n {\n return [\n 'id' => $layout->id_string,\n 'type' => $layout->type,\n ];\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp): self\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n\n return $this;\n }\n\n /**\n * Include Entities.\n */\n public function includeEntities(Layout $layout): FractalResourceCollection\n {\n // Get all top-level sections and their nested fields.\n $entities = $layout->entities()\n ->whereNull('parent_entity_id')\n ->with(['children', 'field.values'])\n ->orderBy('sequence');\n\n $transformer = new LayoutEntityTransformer($this->profile);\n $transformer->setNoDefaultActivityTypeFollowUp($this->noDefaultActivityTypeFollowUp);\n\n return $this->collection($entities->get(), $transformer);\n }\n}","depth":4,"bounds":{"left":0.13364361,"top":0.12210695,"width":0.27759308,"height":0.87789303},"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse League\\Fractal\\Resource\\Collection as FractalResourceCollection;\nuse League\\Fractal\\TransformerAbstract;\n\nclass LayoutTransformer extends TransformerAbstract\n{\n protected array $defaultIncludes = [\n 'entities',\n ];\n\n protected array $availableIncludes = [\n 'entities',\n ];\n private ?Profile $profile;\n\n private bool $noDefaultActivityTypeFollowUp = false;\n\n public function __construct(?Profile $profile = null)\n {\n $this->profile = $profile;\n }\n\n /**\n * A Fractal transformer.\n */\n public function transform(Layout $layout): array\n {\n return [\n 'id' => $layout->id_string,\n 'type' => $layout->type,\n ];\n }\n\n public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp): self\n {\n $this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;\n\n return $this;\n }\n\n /**\n * Include Entities.\n */\n public function includeEntities(Layout $layout): FractalResourceCollection\n {\n // Get all top-level sections and their nested fields.\n $entities = $layout->entities()\n ->whereNull('parent_entity_id')\n ->with(['children', 'field.values'])\n ->orderBy('sequence');\n\n $transformer = new LayoutEntityTransformer($this->profile);\n $transformer->setNoDefaultActivityTypeFollowUp($this->noDefaultActivityTypeFollowUp);\n\n return $this->collection($entities->get(), $transformer);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"bounds":{"left":0.41289893,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"bounds":{"left":0.42154256,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"bounds":{"left":0.4325133,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"bounds":{"left":0.44115692,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"bounds":{"left":0.44980052,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"bounds":{"left":0.46077126,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"bounds":{"left":0.47174203,"top":0.09896249,"width":0.024268618,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"bounds":{"left":0.49833778,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1018882545462990115
|
-4416787288926633499
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
7
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\Profile;
use League\Fractal\Resource\Collection as FractalResourceCollection;
use League\Fractal\TransformerAbstract;
class LayoutTransformer extends TransformerAbstract
{
protected array $defaultIncludes = [
'entities',
];
protected array $availableIncludes = [
'entities',
];
private ?Profile $profile;
private bool $noDefaultActivityTypeFollowUp = false;
public function __construct(?Profile $profile = null)
{
$this->profile = $profile;
}
/**
* A Fractal transformer.
*/
public function transform(Layout $layout): array
{
return [
'id' => $layout->id_string,
'type' => $layout->type,
];
}
public function setNoDefaultActivityTypeFollowUp(bool $noDefaultActivityTypeFollowUp): self
{
$this->noDefaultActivityTypeFollowUp = $noDefaultActivityTypeFollowUp;
return $this;
}
/**
* Include Entities.
*/
public function includeEntities(Layout $layout): FractalResourceCollection
{
// Get all top-level sections and their nested fields.
$entities = $layout->entities()
->whereNull('parent_entity_id')
->with(['children', 'field.values'])
->orderBy('sequence');
$transformer = new LayoutEntityTransformer($this->profile);
$transformer->setNoDefaultActivityTypeFollowUp($this->noDefaultActivityTypeFollowUp);
return $this->collection($entities->get(), $transformer);
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79508
|
2786
|
37
|
2026-05-28T06:32:38.964115+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949958964_m1.jpg...
|
PhpStorm
|
faVsco.js – LayoutTransformer.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
7...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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":"TextRelayServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'TextRelayServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'TextRelayServiceTest'","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":"7","depth":4,"on_screen":true,"role_description":"text"}]...
|
8038334286270312809
|
-8780802033764335166
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
7
SlackFileEditViewGoHistoryWindowHelpDOCKER-₴81DEV (docker)₴2-zshscreenpipe"Fixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated.Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration"is deprecated.Use "@PHP8x0Migration"instead.Rule set "@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-iM.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206masterce9abde868..3800efb7ea JY-20905-tool-search-members-> origin/iorigin/.ad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss*Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-HomeDMsActivityFilesLaterMore+ED→Jiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...° Direct messages&. Petko Kashinski&. Stefka Stoyanova:Todor StamatovSteliyan GeorgievVes% MiraP. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y... O::: Appsã Jira CloudToast100% <Thu 28 May 9:32:38Describe what you are looking forPetko Kashinski6 0Messagest Add canvas@ FilesLukas Kova'**Tuesday, May 12th ~добро утро+Петко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, но 'MultiPicklist' type, a нe single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастихм, не сьм сигуренще проверяMessage Petko Kashinski+...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79505
|
2786
|
36
|
2026-05-28T06:32:32.985692+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949952985_m1.jpg...
|
PhpStorm
|
faVsco.js – CrmController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
48
9
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use DomainException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Jiminny\Contracts\Services\Crm\Provider\SalesforceInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\ServiceUnavailableException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\AccountTransformer;
use Jiminny\Http\Transformers\ContactTransformer;
use Jiminny\Http\Transformers\LayoutTransformer;
use Jiminny\Http\Transformers\LeadTransformer;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Models\Account;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Playbook;
use Jiminny\Models\User;
use Jiminny\Rules\CrmReference;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class CrmController extends Controller
{
private const string MESSAGE_GENERAL_EXCEPTION_SEARCHING = 'Sorry, an internal error occurred whilst searching.';
private const string MESSAGE_GENERAL_EXCEPTION = 'Sorry, an internal error occurred.';
private ?ServiceInterface $crmService = null;
public function __construct(Response $response)
{
parent::__construct($response);
}
/**
* Method for searching for remote records by name.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function search(Request $request): mixed
{
$allowedScopes = [
'lead',
'account',
'contact',
'account-business',
'account-person',
'contact-business',
'contact-person',
];
$request->validate([
'scopes' => 'required|in:' . implode(',', $allowedScopes) . '|array',
'name' => 'required|string|max:100|min:2',
'limit' => 'min:1|max:20',
'offset' => 'min:0',
]);
$scopes = $request->input('scopes');
$name = $request->input('name');
$limit = $request->input('limit', 20);
$offset = $request->input('offset', 0);
$user = $this->getUserFromRequest($request);
try {
$crmService = $this->getCrmServiceWithActiveUser($user);
$crmService->setPage($limit, $offset);
$response = $crmService->find($name, $scopes);
} catch (SocialAccountTokenInvalidException $exception) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (CrmException $exception) {
$response = [];
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return $response;
}
/**
* Method for retrieving remote opportunities by account or contact.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function opportunities(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
try {
$crmProvider = $team->crm->provider;
$request->validate([
'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],
'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],
]);
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($this->request->has('contactId')) {
$contactId = $this->request->input('contactId');
$contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();
// Contact does not exist locally, import it.
if ($contact === null) {
$contact = $crmService->syncContact($contactId);
}
$accountId = $contact->account_id ? $contact->account->crm_provider_id : null;
} else {
$contactId = null;
$accountId = $this->request->input('accountId');
}
$response = $crmService->findOpportunities($accountId, $contactId, $user->getId());
} catch (\InvalidArgumentException $exception) {
$response = $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException $exception) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return $response;
}
/**
* Method for retrieving remote tasks by user.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function activities(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
$crmProvider = $team->crm->provider;
$request->validate([
'objectType' => 'in:lead,contact,account',
'prospectId' => new CrmReference($crmProvider),
'opportunityId' => new CrmReference($crmProvider),
]);
try {
$opportunityId = $request->input('opportunityId');
$objectType = $request->input('objectType');
$objectId = $request->input('prospectId');
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($objectType === null
&& $crmService instanceof SupportsObjectTypeParseInterface
) {
$objectType = $crmService->parseObjectType($objectId);
}
// Take the activity type from the Playbook (default to first for orphaned users).
if ($user->group_id) {
$playbook = $user->group->playbook;
} else {
$playbook = $user->team->playbooks()->first();
// fix empty playbook
if ($playbook === null) {
throw new \InvalidArgumentException('Please configure a Playbook first.');
}
}
if ($crmService instanceof SalesforceInterface) {
/**
* Salesforce support Tasks and Events,
* other crms support only Tasks
*/
$activities = $playbook->activity_type === Playbook::ACTIVITY_TYPE_TASK
? $crmService->getTasks($objectType, $objectId, $opportunityId)
: $crmService->getEvents($objectType, $objectId, $opportunityId);
} else {
$activities = $crmService->getTasks($objectType, $objectId, $opportunityId);
}
} catch (\InvalidArgumentException $exception) {
return $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException $exception) {
return $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
return $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
return $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return [
'activities' => $activities,
'playbookActivityType' => $playbook->activity_type,
];
}
/**
* Method for retrieving remote customer details.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function customers(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
$crmProvider = $team->crm->provider;
$request->validate([
'objectType' => 'in:lead,contact,account,opportunity,undefined',
'providerId' => new CrmReference($crmProvider),
'phoneNumber' => 'phone:INTERNATIONAL,US,' . $user->country_code,
]);
$objectType = $request->input('objectType');
$objectId = $request->input('providerId');
$phoneNumber = $request->input('phoneNumber');
$this->response
->getManager()
->setSerializer(new JsonSerializer());
try {
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($objectId) {
if (($objectType === null || $objectType === 'undefined')
&& $crmService instanceof SupportsObjectTypeParseInterface
) {
$objectType = $crmService->parseObjectType($objectId);
}
switch ($objectType) {
case 'lead':
$lead = $this->getLead($objectId);
$response = $this->response->withItem($lead, new LeadTransformer());
break;
case 'account':
$account = $this->getAccount($objectId);
$response = $this->response->withItem($account, new AccountTransformer());
break;
case 'contact':
$contact = $this->getContact($objectId);
$response = $this->response->withItem($contact, new ContactTransformer());
break;
case 'opportunity':
$opportunity = $this->getOpportunity($objectId);
$response = $this->response->withItem($opportunity->account, new AccountTransformer());
break;
default:
$response = $this->response->errorWrongArgs('Sorry, we don\'t support messaging this type of record.');
break;
}
} elseif ($phoneNumber) {
[$lead, $account, , $contact] = $crmService->matchByPhone(
$phoneNumber,
null,
$user->getId()
);
if ($lead) {
$response = $this->response->withItem($lead, new LeadTransformer());
} elseif ($account) {
$response = $this->response->withItem($account, new AccountTransformer());
} elseif ($contact) {
$response = $this->response->withItem($contact, new ContactTransformer());
} else {
$response = $this->response->errorNotFound('Customer not found.');
}
} else {
$response = $this->response->errorWrongArgs('No search data provided.');
}
} catch (\InvalidArgumentException $exception) {
$response = $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION);
}
return $response;
}
/**
* Rest method for retrieving accounts.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function accounts(): mixed
{
$user = $this->getUserFromRequest($this->request);
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'accountId' => new CrmReference($crmProvider),
]);
$this->response->getManager()->setSerializer(new JsonSerializer());
if ($this->request->has('accountId')) {
$accountId = $this->request->input('accountId');
try {
$account = $this->getAccount($accountId);
$response = $this->response->withItem($account, new AccountTransformer());
} catch (DomainException) {
$response = $this->response->errorNotFound('Record not found.');
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
} else {
$response = $this->response->withCollection($user->team->accounts, new AccountTransformer());
}
return $response;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $accountId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return Account
*/
private function getAccount(string $accountId): Account
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$account = $team->crm->accounts()->where('crm_provider_id', $accountId)->first();
if ($account instanceof Account) {
return $account;
}
// Account does not exist locally, import it.
try {
return $this->getCrmServiceWithActiveUser($user)->syncAccount($accountId);
} catch (SocialAccountTokenInvalidException $exception) {
return $this->response->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.'
);
}
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $opportunityId
*
* @throws DomainException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Opportunity
*/
private function getOpportunity(string $opportunityId): Opportunity
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if (! $opportunity instanceof Opportunity) {
$crmService = $this->getCrmServiceWithActiveUser($user);
$opportunity = $crmService->syncOpportunity($opportunityId);
}
// Sanity check.
if ($user->team_id !== $opportunity->account->team_id) {
throw new DomainException('Opportunity not found.');
}
return $opportunity;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $contactId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Contact
*/
private function getContact(string $contactId): Contact
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$crmService = $this->getCrmServiceWithActiveUser($user);
$contact = $crmService->syncContact($contactId);
}
return $contact;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $leadId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Lead
*/
private function getLead(string $leadId): Lead
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$lead = $team->crm->leads()->where('crm_provider_id', $leadId)->first();
if ($lead instanceof Lead) {
return $lead;
}
// Lead does not exist locally, import it.
return $this->getCrmServiceWithActiveUser($user)->syncLead($leadId);
}
/**
* Rest method for retrieving contacts.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function contacts(): mixed
{
$user = $this->request->user();
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],
'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],
]);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
try {
// Determine if they wish to retrieve a single contact or multiple for an account.
if ($this->request->has('contactId')) {
$contactId = $this->request->input('contactId');
$contact = $this->getContact($contactId);
$response = $this->response->withItem($contact, new ContactTransformer());
} else {
$accountId = $this->request->input('accountId');
$account = $this->getAccount($accountId);
$response = $this->response->withCollection($account->contacts, new ContactTransformer());
}
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
return $response;
}
/**
* Rest method for retrieving leads.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function leads(): mixed
{
$user = $this->request->user();
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'leadId' => new CrmReference($crmProvider),
]);
$this->response
->getManager()
->setSerializer(new JsonSerializer())
->parseIncludes(['stage', 'recordType']);
if ($this->request->has('leadId')) {
$leadId = $this->request->input('leadId');
try {
$lead = $this->getLead($leadId);
$response = $this->response->withItem($lead, new LeadTransformer());
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
} else {
$response = $this->response->withCollection($user->team->leads, new LeadTransformer());
}
return $response;
}
/**
* @param Request $request
*
* @throws ValidationException
*
* @return JsonResponse
*/
public function layouts(Request $request): JsonResponse
{
$request->validate([
'type' => 'required|in:' . implode(',', Layout::$enumTypes),
]);
$user = $request->user();
$type = $request->input('type');
// Take the activity type from the Playbook (default to first for orphaned users).
if ($user->group_id) {
$playbook = $user->group->playbook;
} else {
/** @var Playbook $playbook */
$playbook = $user->team->playbooks()->first();
}
if ($playbook === null) {
return $this->response->errorUnprocessable('Please configure a Playbook first.');
}
$layoutTypeParts = explode('-', $type);
$layoutType = sprintf(
'%s-%s',
reset($layoutTypeParts),
end($layoutTypeParts)
);
/** @var Layout|null $layout */
$layout = $playbook->layouts()
->where('name', ucfirst($playbook->activity_type) . ' Based Layout')
->where('type', $layoutType)
->first();
if ($layout === null) {
return $this->response->errorNotFound('Layout not found.');
}
$this->response
->getManager()
->setSerializer(new JsonSerializer())
->parseIncludes([
'entities.children.field.options',
]);
$transformer = new LayoutTransformer($user->crmProfile)
->setNoDefaultActivityTypeFollowUp(true)
;
return $this->response->withItem($layout, $transformer);
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmServiceWithActiveUser(User $user): ServiceInterface
{
if ($this->crmService === null) {
$team = $user->getTeam();
if (! $user->isCrmRequired()) {
$integrationAdmin = $team->getOwner();
} else {
$integrationAdmin = $user;
}
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $integrationAdmin,
'providerSlug' => $team->getCrmConfiguration()->getProviderName(),
]);
$this->crmService = $crmResolver->prepareCrmService();
}
return $this->crmService;
}
}
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
21
1
18
2
6
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id
where u.team_id = 1;
SELECT * FROM social_accounts WHERE sociable_id = 1635;
SELECT * FROM users WHERE id = 1635;
select * from teams where id = 1;
select * from users where team_id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role;
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
SELECT * FROM automated_reports where id = 71;
SELECT * FROM automated_report_results where report_id = 71;
UPDATE automated_reports set playbook_categories = NULL where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT `automated_report_results`.* FROM `automated_report_results`
INNER JOIN `automated_reports`
ON `automated_report_results`.`report_id` = `automated_reports`.`id`
WHERE 1=1
AND `automated_report_results`.`generated_at` IS NOT NULL
# AND `automated_report_results`.`sent_at` IS NOT NULL
AND `automated_reports`.`team_id` = 1
AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$."users"')
;
SELECT * FROM automated_reports where id = 67;
SELECT * FROM automated_reports where id = 42;
SELECT * FROM users WHERE id = 143; # group 28
select * from teams where id = 3143;
select * from crm_configurations where id = 500;
select * from users where name = 'Integration Account'; # 1695
SELECT * FROM social_accounts WHERE sociable_id = 1695;
select * from activities where crm_configuration_id = 39
and recording_state = 'recorded' and duration > 60
and status = 'completed' and actual_start_time >= '2025-12-01';
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;
select * from leads;
SELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003
SELECT * FROM activities WHERE id IN (16,422003);
SELECT * FROM activities where status = 'failed';
SELECT * FROM tracks WHERE activity_id = 422003;
SELECT
a.*
FROM activities a
JOIN users u ON a.user_id = u.id
WHERE
a.status = 'completed'
AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid
AND a.deleted_at IS NULL
AND EXISTS (
SELECT 1 FROM tracks t
WHERE t.activity_id = a.id
AND t.type IN ('audio', 'video')
)
ORDER BY a.actual_start_time DESC
LIMIT 25;
select * from teams where id = 19;
select * from crm_configurations where provider = 'pipedrive';
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 = 19 and sa.provider = 'pipedrive';
SELECT * FROM social_accounts WHERE id = 1116;
UPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',
provider_refresh_token = '5034113:[TELEGRAM_TOKEN]b2bfc',
expires = 1779091997,
state = 'connected'
WHERE id = 1116;
"provider_user_token": "v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA",
"provider_refresh_token": "5034113:[TELEGRAM_TOKEN]b2bfc",
"expires": 1779091997,
select * from crm_field_values;
select * from crm_fields where type = 'multi-picklist';
SELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
SELECT * FROM crm_fields WHERE id = 3014; # 1885
SELECT * FROM crm_field_values WHERE crm_field_id = 3014;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20915-fix-missing-header-text-relay, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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":"TextRelayServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'TextRelayServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'TextRelayServiceTest'","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":"48","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"9","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse DomainException;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\SalesforceInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\ServiceUnavailableException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\AccountTransformer;\nuse Jiminny\\Http\\Transformers\\ContactTransformer;\nuse Jiminny\\Http\\Transformers\\LayoutTransformer;\nuse Jiminny\\Http\\Transformers\\LeadTransformer;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass CrmController extends Controller\n{\n private const string MESSAGE_GENERAL_EXCEPTION_SEARCHING = 'Sorry, an internal error occurred whilst searching.';\n private const string MESSAGE_GENERAL_EXCEPTION = 'Sorry, an internal error occurred.';\n private ?ServiceInterface $crmService = null;\n\n public function __construct(Response $response)\n {\n parent::__construct($response);\n }\n\n /**\n * Method for searching for remote records by name.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function search(Request $request): mixed\n {\n $allowedScopes = [\n 'lead',\n 'account',\n 'contact',\n 'account-business',\n 'account-person',\n 'contact-business',\n 'contact-person',\n ];\n\n $request->validate([\n 'scopes' => 'required|in:' . implode(',', $allowedScopes) . '|array',\n 'name' => 'required|string|max:100|min:2',\n 'limit' => 'min:1|max:20',\n 'offset' => 'min:0',\n ]);\n\n $scopes = $request->input('scopes');\n $name = $request->input('name');\n $limit = $request->input('limit', 20);\n $offset = $request->input('offset', 0);\n $user = $this->getUserFromRequest($request);\n\n try {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n $crmService->setPage($limit, $offset);\n\n $response = $crmService->find($name, $scopes);\n } catch (SocialAccountTokenInvalidException $exception) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (CrmException $exception) {\n $response = [];\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return $response;\n }\n\n /**\n * Method for retrieving remote opportunities by account or contact.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function opportunities(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n\n try {\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],\n 'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],\n ]);\n\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($this->request->has('contactId')) {\n $contactId = $this->request->input('contactId');\n\n $contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();\n\n // Contact does not exist locally, import it.\n if ($contact === null) {\n $contact = $crmService->syncContact($contactId);\n }\n\n $accountId = $contact->account_id ? $contact->account->crm_provider_id : null;\n } else {\n $contactId = null;\n $accountId = $this->request->input('accountId');\n }\n\n $response = $crmService->findOpportunities($accountId, $contactId, $user->getId());\n } catch (\\InvalidArgumentException $exception) {\n $response = $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException $exception) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return $response;\n }\n\n /**\n * Method for retrieving remote tasks by user.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function activities(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'objectType' => 'in:lead,contact,account',\n 'prospectId' => new CrmReference($crmProvider),\n 'opportunityId' => new CrmReference($crmProvider),\n ]);\n\n try {\n $opportunityId = $request->input('opportunityId');\n $objectType = $request->input('objectType');\n $objectId = $request->input('prospectId');\n\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($objectType === null\n && $crmService instanceof SupportsObjectTypeParseInterface\n ) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n\n // Take the activity type from the Playbook (default to first for orphaned users).\n if ($user->group_id) {\n $playbook = $user->group->playbook;\n } else {\n $playbook = $user->team->playbooks()->first();\n\n // fix empty playbook\n if ($playbook === null) {\n throw new \\InvalidArgumentException('Please configure a Playbook first.');\n }\n }\n\n if ($crmService instanceof SalesforceInterface) {\n /**\n * Salesforce support Tasks and Events,\n * other crms support only Tasks\n */\n $activities = $playbook->activity_type === Playbook::ACTIVITY_TYPE_TASK\n ? $crmService->getTasks($objectType, $objectId, $opportunityId)\n : $crmService->getEvents($objectType, $objectId, $opportunityId);\n } else {\n $activities = $crmService->getTasks($objectType, $objectId, $opportunityId);\n }\n } catch (\\InvalidArgumentException $exception) {\n return $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException $exception) {\n return $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n return $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n\n return $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return [\n 'activities' => $activities,\n 'playbookActivityType' => $playbook->activity_type,\n ];\n }\n\n /**\n * Method for retrieving remote customer details.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function customers(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'objectType' => 'in:lead,contact,account,opportunity,undefined',\n 'providerId' => new CrmReference($crmProvider),\n 'phoneNumber' => 'phone:INTERNATIONAL,US,' . $user->country_code,\n ]);\n\n $objectType = $request->input('objectType');\n $objectId = $request->input('providerId');\n $phoneNumber = $request->input('phoneNumber');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n try {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($objectId) {\n if (($objectType === null || $objectType === 'undefined')\n && $crmService instanceof SupportsObjectTypeParseInterface\n ) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n\n switch ($objectType) {\n case 'lead':\n $lead = $this->getLead($objectId);\n $response = $this->response->withItem($lead, new LeadTransformer());\n\n break;\n\n case 'account':\n $account = $this->getAccount($objectId);\n $response = $this->response->withItem($account, new AccountTransformer());\n\n break;\n\n case 'contact':\n $contact = $this->getContact($objectId);\n $response = $this->response->withItem($contact, new ContactTransformer());\n\n break;\n\n case 'opportunity':\n $opportunity = $this->getOpportunity($objectId);\n $response = $this->response->withItem($opportunity->account, new AccountTransformer());\n\n break;\n\n default:\n $response = $this->response->errorWrongArgs('Sorry, we don\\'t support messaging this type of record.');\n\n break;\n }\n } elseif ($phoneNumber) {\n [$lead, $account, , $contact] = $crmService->matchByPhone(\n $phoneNumber,\n null,\n $user->getId()\n );\n\n if ($lead) {\n $response = $this->response->withItem($lead, new LeadTransformer());\n } elseif ($account) {\n $response = $this->response->withItem($account, new AccountTransformer());\n } elseif ($contact) {\n $response = $this->response->withItem($contact, new ContactTransformer());\n } else {\n $response = $this->response->errorNotFound('Customer not found.');\n }\n } else {\n $response = $this->response->errorWrongArgs('No search data provided.');\n }\n } catch (\\InvalidArgumentException $exception) {\n $response = $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION);\n }\n\n return $response;\n }\n\n /**\n * Rest method for retrieving accounts.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function accounts(): mixed\n {\n $user = $this->getUserFromRequest($this->request);\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'accountId' => new CrmReference($crmProvider),\n ]);\n\n $this->response->getManager()->setSerializer(new JsonSerializer());\n\n if ($this->request->has('accountId')) {\n $accountId = $this->request->input('accountId');\n\n try {\n $account = $this->getAccount($accountId);\n\n $response = $this->response->withItem($account, new AccountTransformer());\n } catch (DomainException) {\n $response = $this->response->errorNotFound('Record not found.');\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n } else {\n $response = $this->response->withCollection($user->team->accounts, new AccountTransformer());\n }\n\n return $response;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $accountId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return Account\n */\n private function getAccount(string $accountId): Account\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountId)->first();\n\n if ($account instanceof Account) {\n return $account;\n }\n\n // Account does not exist locally, import it.\n try {\n return $this->getCrmServiceWithActiveUser($user)->syncAccount($accountId);\n } catch (SocialAccountTokenInvalidException $exception) {\n return $this->response->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.'\n );\n }\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $opportunityId\n *\n * @throws DomainException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Opportunity\n */\n private function getOpportunity(string $opportunityId): Opportunity\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if (! $opportunity instanceof Opportunity) {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n // Sanity check.\n if ($user->team_id !== $opportunity->account->team_id) {\n throw new DomainException('Opportunity not found.');\n }\n\n return $opportunity;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $contactId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Contact\n */\n private function getContact(string $contactId): Contact\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n $contact = $crmService->syncContact($contactId);\n }\n\n return $contact;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $leadId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Lead\n */\n private function getLead(string $leadId): Lead\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $lead = $team->crm->leads()->where('crm_provider_id', $leadId)->first();\n\n if ($lead instanceof Lead) {\n return $lead;\n }\n\n // Lead does not exist locally, import it.\n return $this->getCrmServiceWithActiveUser($user)->syncLead($leadId);\n }\n\n /**\n * Rest method for retrieving contacts.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function contacts(): mixed\n {\n $user = $this->request->user();\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],\n 'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n try {\n // Determine if they wish to retrieve a single contact or multiple for an account.\n if ($this->request->has('contactId')) {\n $contactId = $this->request->input('contactId');\n $contact = $this->getContact($contactId);\n\n $response = $this->response->withItem($contact, new ContactTransformer());\n } else {\n $accountId = $this->request->input('accountId');\n $account = $this->getAccount($accountId);\n\n $response = $this->response->withCollection($account->contacts, new ContactTransformer());\n }\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n\n return $response;\n }\n\n /**\n * Rest method for retrieving leads.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function leads(): mixed\n {\n $user = $this->request->user();\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'leadId' => new CrmReference($crmProvider),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer())\n ->parseIncludes(['stage', 'recordType']);\n\n if ($this->request->has('leadId')) {\n $leadId = $this->request->input('leadId');\n\n try {\n $lead = $this->getLead($leadId);\n\n $response = $this->response->withItem($lead, new LeadTransformer());\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n } else {\n $response = $this->response->withCollection($user->team->leads, new LeadTransformer());\n }\n\n return $response;\n }\n\n /**\n * @param Request $request\n *\n * @throws ValidationException\n *\n * @return JsonResponse\n */\n public function layouts(Request $request): JsonResponse\n {\n $request->validate([\n 'type' => 'required|in:' . implode(',', Layout::$enumTypes),\n ]);\n\n $user = $request->user();\n $type = $request->input('type');\n\n // Take the activity type from the Playbook (default to first for orphaned users).\n if ($user->group_id) {\n $playbook = $user->group->playbook;\n } else {\n /** @var Playbook $playbook */\n $playbook = $user->team->playbooks()->first();\n }\n\n if ($playbook === null) {\n return $this->response->errorUnprocessable('Please configure a Playbook first.');\n }\n\n $layoutTypeParts = explode('-', $type);\n\n $layoutType = sprintf(\n '%s-%s',\n reset($layoutTypeParts),\n end($layoutTypeParts)\n );\n\n /** @var Layout|null $layout */\n $layout = $playbook->layouts()\n ->where('name', ucfirst($playbook->activity_type) . ' Based Layout')\n ->where('type', $layoutType)\n ->first();\n\n if ($layout === null) {\n return $this->response->errorNotFound('Layout not found.');\n }\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer())\n ->parseIncludes([\n 'entities.children.field.options',\n ]);\n\n $transformer = new LayoutTransformer($user->crmProfile)\n ->setNoDefaultActivityTypeFollowUp(true)\n ;\n\n return $this->response->withItem($layout, $transformer);\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmServiceWithActiveUser(User $user): ServiceInterface\n {\n if ($this->crmService === null) {\n $team = $user->getTeam();\n\n if (! $user->isCrmRequired()) {\n $integrationAdmin = $team->getOwner();\n } else {\n $integrationAdmin = $user;\n }\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $integrationAdmin,\n 'providerSlug' => $team->getCrmConfiguration()->getProviderName(),\n ]);\n\n $this->crmService = $crmResolver->prepareCrmService();\n }\n\n return $this->crmService;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse DomainException;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\SalesforceInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\ServiceUnavailableException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\AccountTransformer;\nuse Jiminny\\Http\\Transformers\\ContactTransformer;\nuse Jiminny\\Http\\Transformers\\LayoutTransformer;\nuse Jiminny\\Http\\Transformers\\LeadTransformer;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass CrmController extends Controller\n{\n private const string MESSAGE_GENERAL_EXCEPTION_SEARCHING = 'Sorry, an internal error occurred whilst searching.';\n private const string MESSAGE_GENERAL_EXCEPTION = 'Sorry, an internal error occurred.';\n private ?ServiceInterface $crmService = null;\n\n public function __construct(Response $response)\n {\n parent::__construct($response);\n }\n\n /**\n * Method for searching for remote records by name.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function search(Request $request): mixed\n {\n $allowedScopes = [\n 'lead',\n 'account',\n 'contact',\n 'account-business',\n 'account-person',\n 'contact-business',\n 'contact-person',\n ];\n\n $request->validate([\n 'scopes' => 'required|in:' . implode(',', $allowedScopes) . '|array',\n 'name' => 'required|string|max:100|min:2',\n 'limit' => 'min:1|max:20',\n 'offset' => 'min:0',\n ]);\n\n $scopes = $request->input('scopes');\n $name = $request->input('name');\n $limit = $request->input('limit', 20);\n $offset = $request->input('offset', 0);\n $user = $this->getUserFromRequest($request);\n\n try {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n $crmService->setPage($limit, $offset);\n\n $response = $crmService->find($name, $scopes);\n } catch (SocialAccountTokenInvalidException $exception) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (CrmException $exception) {\n $response = [];\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return $response;\n }\n\n /**\n * Method for retrieving remote opportunities by account or contact.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function opportunities(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n\n try {\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],\n 'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],\n ]);\n\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($this->request->has('contactId')) {\n $contactId = $this->request->input('contactId');\n\n $contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();\n\n // Contact does not exist locally, import it.\n if ($contact === null) {\n $contact = $crmService->syncContact($contactId);\n }\n\n $accountId = $contact->account_id ? $contact->account->crm_provider_id : null;\n } else {\n $contactId = null;\n $accountId = $this->request->input('accountId');\n }\n\n $response = $crmService->findOpportunities($accountId, $contactId, $user->getId());\n } catch (\\InvalidArgumentException $exception) {\n $response = $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException $exception) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return $response;\n }\n\n /**\n * Method for retrieving remote tasks by user.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function activities(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'objectType' => 'in:lead,contact,account',\n 'prospectId' => new CrmReference($crmProvider),\n 'opportunityId' => new CrmReference($crmProvider),\n ]);\n\n try {\n $opportunityId = $request->input('opportunityId');\n $objectType = $request->input('objectType');\n $objectId = $request->input('prospectId');\n\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($objectType === null\n && $crmService instanceof SupportsObjectTypeParseInterface\n ) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n\n // Take the activity type from the Playbook (default to first for orphaned users).\n if ($user->group_id) {\n $playbook = $user->group->playbook;\n } else {\n $playbook = $user->team->playbooks()->first();\n\n // fix empty playbook\n if ($playbook === null) {\n throw new \\InvalidArgumentException('Please configure a Playbook first.');\n }\n }\n\n if ($crmService instanceof SalesforceInterface) {\n /**\n * Salesforce support Tasks and Events,\n * other crms support only Tasks\n */\n $activities = $playbook->activity_type === Playbook::ACTIVITY_TYPE_TASK\n ? $crmService->getTasks($objectType, $objectId, $opportunityId)\n : $crmService->getEvents($objectType, $objectId, $opportunityId);\n } else {\n $activities = $crmService->getTasks($objectType, $objectId, $opportunityId);\n }\n } catch (\\InvalidArgumentException $exception) {\n return $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException $exception) {\n return $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n return $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n\n return $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return [\n 'activities' => $activities,\n 'playbookActivityType' => $playbook->activity_type,\n ];\n }\n\n /**\n * Method for retrieving remote customer details.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function customers(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'objectType' => 'in:lead,contact,account,opportunity,undefined',\n 'providerId' => new CrmReference($crmProvider),\n 'phoneNumber' => 'phone:INTERNATIONAL,US,' . $user->country_code,\n ]);\n\n $objectType = $request->input('objectType');\n $objectId = $request->input('providerId');\n $phoneNumber = $request->input('phoneNumber');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n try {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($objectId) {\n if (($objectType === null || $objectType === 'undefined')\n && $crmService instanceof SupportsObjectTypeParseInterface\n ) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n\n switch ($objectType) {\n case 'lead':\n $lead = $this->getLead($objectId);\n $response = $this->response->withItem($lead, new LeadTransformer());\n\n break;\n\n case 'account':\n $account = $this->getAccount($objectId);\n $response = $this->response->withItem($account, new AccountTransformer());\n\n break;\n\n case 'contact':\n $contact = $this->getContact($objectId);\n $response = $this->response->withItem($contact, new ContactTransformer());\n\n break;\n\n case 'opportunity':\n $opportunity = $this->getOpportunity($objectId);\n $response = $this->response->withItem($opportunity->account, new AccountTransformer());\n\n break;\n\n default:\n $response = $this->response->errorWrongArgs('Sorry, we don\\'t support messaging this type of record.');\n\n break;\n }\n } elseif ($phoneNumber) {\n [$lead, $account, , $contact] = $crmService->matchByPhone(\n $phoneNumber,\n null,\n $user->getId()\n );\n\n if ($lead) {\n $response = $this->response->withItem($lead, new LeadTransformer());\n } elseif ($account) {\n $response = $this->response->withItem($account, new AccountTransformer());\n } elseif ($contact) {\n $response = $this->response->withItem($contact, new ContactTransformer());\n } else {\n $response = $this->response->errorNotFound('Customer not found.');\n }\n } else {\n $response = $this->response->errorWrongArgs('No search data provided.');\n }\n } catch (\\InvalidArgumentException $exception) {\n $response = $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION);\n }\n\n return $response;\n }\n\n /**\n * Rest method for retrieving accounts.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function accounts(): mixed\n {\n $user = $this->getUserFromRequest($this->request);\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'accountId' => new CrmReference($crmProvider),\n ]);\n\n $this->response->getManager()->setSerializer(new JsonSerializer());\n\n if ($this->request->has('accountId')) {\n $accountId = $this->request->input('accountId');\n\n try {\n $account = $this->getAccount($accountId);\n\n $response = $this->response->withItem($account, new AccountTransformer());\n } catch (DomainException) {\n $response = $this->response->errorNotFound('Record not found.');\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n } else {\n $response = $this->response->withCollection($user->team->accounts, new AccountTransformer());\n }\n\n return $response;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $accountId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return Account\n */\n private function getAccount(string $accountId): Account\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountId)->first();\n\n if ($account instanceof Account) {\n return $account;\n }\n\n // Account does not exist locally, import it.\n try {\n return $this->getCrmServiceWithActiveUser($user)->syncAccount($accountId);\n } catch (SocialAccountTokenInvalidException $exception) {\n return $this->response->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.'\n );\n }\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $opportunityId\n *\n * @throws DomainException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Opportunity\n */\n private function getOpportunity(string $opportunityId): Opportunity\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if (! $opportunity instanceof Opportunity) {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n // Sanity check.\n if ($user->team_id !== $opportunity->account->team_id) {\n throw new DomainException('Opportunity not found.');\n }\n\n return $opportunity;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $contactId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Contact\n */\n private function getContact(string $contactId): Contact\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n $contact = $crmService->syncContact($contactId);\n }\n\n return $contact;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $leadId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Lead\n */\n private function getLead(string $leadId): Lead\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $lead = $team->crm->leads()->where('crm_provider_id', $leadId)->first();\n\n if ($lead instanceof Lead) {\n return $lead;\n }\n\n // Lead does not exist locally, import it.\n return $this->getCrmServiceWithActiveUser($user)->syncLead($leadId);\n }\n\n /**\n * Rest method for retrieving contacts.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function contacts(): mixed\n {\n $user = $this->request->user();\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],\n 'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n try {\n // Determine if they wish to retrieve a single contact or multiple for an account.\n if ($this->request->has('contactId')) {\n $contactId = $this->request->input('contactId');\n $contact = $this->getContact($contactId);\n\n $response = $this->response->withItem($contact, new ContactTransformer());\n } else {\n $accountId = $this->request->input('accountId');\n $account = $this->getAccount($accountId);\n\n $response = $this->response->withCollection($account->contacts, new ContactTransformer());\n }\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n\n return $response;\n }\n\n /**\n * Rest method for retrieving leads.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function leads(): mixed\n {\n $user = $this->request->user();\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'leadId' => new CrmReference($crmProvider),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer())\n ->parseIncludes(['stage', 'recordType']);\n\n if ($this->request->has('leadId')) {\n $leadId = $this->request->input('leadId');\n\n try {\n $lead = $this->getLead($leadId);\n\n $response = $this->response->withItem($lead, new LeadTransformer());\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n } else {\n $response = $this->response->withCollection($user->team->leads, new LeadTransformer());\n }\n\n return $response;\n }\n\n /**\n * @param Request $request\n *\n * @throws ValidationException\n *\n * @return JsonResponse\n */\n public function layouts(Request $request): JsonResponse\n {\n $request->validate([\n 'type' => 'required|in:' . implode(',', Layout::$enumTypes),\n ]);\n\n $user = $request->user();\n $type = $request->input('type');\n\n // Take the activity type from the Playbook (default to first for orphaned users).\n if ($user->group_id) {\n $playbook = $user->group->playbook;\n } else {\n /** @var Playbook $playbook */\n $playbook = $user->team->playbooks()->first();\n }\n\n if ($playbook === null) {\n return $this->response->errorUnprocessable('Please configure a Playbook first.');\n }\n\n $layoutTypeParts = explode('-', $type);\n\n $layoutType = sprintf(\n '%s-%s',\n reset($layoutTypeParts),\n end($layoutTypeParts)\n );\n\n /** @var Layout|null $layout */\n $layout = $playbook->layouts()\n ->where('name', ucfirst($playbook->activity_type) . ' Based Layout')\n ->where('type', $layoutType)\n ->first();\n\n if ($layout === null) {\n return $this->response->errorNotFound('Layout not found.');\n }\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer())\n ->parseIncludes([\n 'entities.children.field.options',\n ]);\n\n $transformer = new LayoutTransformer($user->crmProfile)\n ->setNoDefaultActivityTypeFollowUp(true)\n ;\n\n return $this->response->withItem($layout, $transformer);\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmServiceWithActiveUser(User $user): ServiceInterface\n {\n if ($this->crmService === null) {\n $team = $user->getTeam();\n\n if (! $user->isCrmRequired()) {\n $integrationAdmin = $team->getOwner();\n } else {\n $integrationAdmin = $user;\n }\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $integrationAdmin,\n 'providerSlug' => $team->getCrmConfiguration()->getProviderName(),\n ]);\n\n $this->crmService = $crmResolver->prepareCrmService();\n }\n\n return $this->crmService;\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"21","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"18","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"6","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\n\nselect sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id\nwhere u.team_id = 1;\nSELECT * FROM social_accounts WHERE sociable_id = 1635;\nSELECT * FROM users WHERE id = 1635;\n\nselect * from teams where id = 1;\nselect * from users where team_id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role;\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\nSELECT * FROM automated_reports where id = 71;\nSELECT * FROM automated_report_results where report_id = 71;\nUPDATE automated_reports set playbook_categories = NULL where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT `automated_report_results`.* FROM `automated_report_results`\nINNER JOIN `automated_reports`\n ON `automated_report_results`.`report_id` = `automated_reports`.`id`\nWHERE 1=1\n AND `automated_report_results`.`generated_at` IS NOT NULL\n# AND `automated_report_results`.`sent_at` IS NOT NULL\n AND `automated_reports`.`team_id` = 1\n AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$.\"users\"')\n;\n\nSELECT * FROM automated_reports where id = 67;\nSELECT * FROM automated_reports where id = 42;\nSELECT * FROM users WHERE id = 143; # group 28\n\nselect * from teams where id = 3143;\nselect * from crm_configurations where id = 500;\nselect * from users where name = 'Integration Account'; # 1695\nSELECT * FROM social_accounts WHERE sociable_id = 1695;\n\nselect * from activities where crm_configuration_id = 39\nand recording_state = 'recorded' and duration > 60\nand status = 'completed' and actual_start_time >= '2025-12-01';\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;\n\nselect * from leads;\n\nSELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003\nSELECT * FROM activities WHERE id IN (16,422003);\nSELECT * FROM activities where status = 'failed';\n\nSELECT * FROM tracks WHERE activity_id = 422003;\n\nSELECT\n a.*\nFROM activities a\nJOIN users u ON a.user_id = u.id\nWHERE\n a.status = 'completed'\n AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid\n AND a.deleted_at IS NULL\n AND EXISTS (\n SELECT 1 FROM tracks t\n WHERE t.activity_id = a.id\n AND t.type IN ('audio', 'video')\n )\nORDER BY a.actual_start_time DESC\nLIMIT 25;\n\nselect * from teams where id = 19;\nselect * from crm_configurations where provider = 'pipedrive';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 19 and sa.provider = 'pipedrive';\n\nSELECT * FROM social_accounts WHERE id = 1116;\n\nUPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',\nprovider_refresh_token = '5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc',\nexpires = 1779091997,\nstate = 'connected'\nWHERE id = 1116;\n\n \"provider_user_token\": \"v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA\",\n \"provider_refresh_token\": \"5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc\",\n \"expires\": 1779091997,\n\nselect * from crm_field_values;\n\nselect * from crm_fields where type = 'multi-picklist';\nSELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\nSELECT * FROM crm_fields WHERE id = 3014; # 1885\nSELECT * FROM crm_field_values WHERE crm_field_id = 3014;","depth":4,"on_screen":true,"value":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\n\nselect sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id\nwhere u.team_id = 1;\nSELECT * FROM social_accounts WHERE sociable_id = 1635;\nSELECT * FROM users WHERE id = 1635;\n\nselect * from teams where id = 1;\nselect * from users where team_id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role;\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\nSELECT * FROM automated_reports where id = 71;\nSELECT * FROM automated_report_results where report_id = 71;\nUPDATE automated_reports set playbook_categories = NULL where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT `automated_report_results`.* FROM `automated_report_results`\nINNER JOIN `automated_reports`\n ON `automated_report_results`.`report_id` = `automated_reports`.`id`\nWHERE 1=1\n AND `automated_report_results`.`generated_at` IS NOT NULL\n# AND `automated_report_results`.`sent_at` IS NOT NULL\n AND `automated_reports`.`team_id` = 1\n AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$.\"users\"')\n;\n\nSELECT * FROM automated_reports where id = 67;\nSELECT * FROM automated_reports where id = 42;\nSELECT * FROM users WHERE id = 143; # group 28\n\nselect * from teams where id = 3143;\nselect * from crm_configurations where id = 500;\nselect * from users where name = 'Integration Account'; # 1695\nSELECT * FROM social_accounts WHERE sociable_id = 1695;\n\nselect * from activities where crm_configuration_id = 39\nand recording_state = 'recorded' and duration > 60\nand status = 'completed' and actual_start_time >= '2025-12-01';\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;\n\nselect * from leads;\n\nSELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003\nSELECT * FROM activities WHERE id IN (16,422003);\nSELECT * FROM activities where status = 'failed';\n\nSELECT * FROM tracks WHERE activity_id = 422003;\n\nSELECT\n a.*\nFROM activities a\nJOIN users u ON a.user_id = u.id\nWHERE\n a.status = 'completed'\n AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid\n AND a.deleted_at IS NULL\n AND EXISTS (\n SELECT 1 FROM tracks t\n WHERE t.activity_id = a.id\n AND t.type IN ('audio', 'video')\n )\nORDER BY a.actual_start_time DESC\nLIMIT 25;\n\nselect * from teams where id = 19;\nselect * from crm_configurations where provider = 'pipedrive';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 19 and sa.provider = 'pipedrive';\n\nSELECT * FROM social_accounts WHERE id = 1116;\n\nUPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',\nprovider_refresh_token = '5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc',\nexpires = 1779091997,\nstate = 'connected'\nWHERE id = 1116;\n\n \"provider_user_token\": \"v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA\",\n \"provider_refresh_token\": \"5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc\",\n \"expires\": 1779091997,\n\nselect * from crm_field_values;\n\nselect * from crm_fields where type = 'multi-picklist';\nSELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\nSELECT * FROM crm_fields WHERE id = 3014; # 1885\nSELECT * FROM crm_field_values WHERE crm_field_id = 3014;","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}]...
|
1956647833605094083
|
-2607692967562570153
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
48
9
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use DomainException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Jiminny\Contracts\Services\Crm\Provider\SalesforceInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\ServiceUnavailableException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\AccountTransformer;
use Jiminny\Http\Transformers\ContactTransformer;
use Jiminny\Http\Transformers\LayoutTransformer;
use Jiminny\Http\Transformers\LeadTransformer;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Models\Account;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Playbook;
use Jiminny\Models\User;
use Jiminny\Rules\CrmReference;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class CrmController extends Controller
{
private const string MESSAGE_GENERAL_EXCEPTION_SEARCHING = 'Sorry, an internal error occurred whilst searching.';
private const string MESSAGE_GENERAL_EXCEPTION = 'Sorry, an internal error occurred.';
private ?ServiceInterface $crmService = null;
public function __construct(Response $response)
{
parent::__construct($response);
}
/**
* Method for searching for remote records by name.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function search(Request $request): mixed
{
$allowedScopes = [
'lead',
'account',
'contact',
'account-business',
'account-person',
'contact-business',
'contact-person',
];
$request->validate([
'scopes' => 'required|in:' . implode(',', $allowedScopes) . '|array',
'name' => 'required|string|max:100|min:2',
'limit' => 'min:1|max:20',
'offset' => 'min:0',
]);
$scopes = $request->input('scopes');
$name = $request->input('name');
$limit = $request->input('limit', 20);
$offset = $request->input('offset', 0);
$user = $this->getUserFromRequest($request);
try {
$crmService = $this->getCrmServiceWithActiveUser($user);
$crmService->setPage($limit, $offset);
$response = $crmService->find($name, $scopes);
} catch (SocialAccountTokenInvalidException $exception) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (CrmException $exception) {
$response = [];
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return $response;
}
/**
* Method for retrieving remote opportunities by account or contact.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function opportunities(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
try {
$crmProvider = $team->crm->provider;
$request->validate([
'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],
'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],
]);
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($this->request->has('contactId')) {
$contactId = $this->request->input('contactId');
$contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();
// Contact does not exist locally, import it.
if ($contact === null) {
$contact = $crmService->syncContact($contactId);
}
$accountId = $contact->account_id ? $contact->account->crm_provider_id : null;
} else {
$contactId = null;
$accountId = $this->request->input('accountId');
}
$response = $crmService->findOpportunities($accountId, $contactId, $user->getId());
} catch (\InvalidArgumentException $exception) {
$response = $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException $exception) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return $response;
}
/**
* Method for retrieving remote tasks by user.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function activities(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
$crmProvider = $team->crm->provider;
$request->validate([
'objectType' => 'in:lead,contact,account',
'prospectId' => new CrmReference($crmProvider),
'opportunityId' => new CrmReference($crmProvider),
]);
try {
$opportunityId = $request->input('opportunityId');
$objectType = $request->input('objectType');
$objectId = $request->input('prospectId');
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($objectType === null
&& $crmService instanceof SupportsObjectTypeParseInterface
) {
$objectType = $crmService->parseObjectType($objectId);
}
// Take the activity type from the Playbook (default to first for orphaned users).
if ($user->group_id) {
$playbook = $user->group->playbook;
} else {
$playbook = $user->team->playbooks()->first();
// fix empty playbook
if ($playbook === null) {
throw new \InvalidArgumentException('Please configure a Playbook first.');
}
}
if ($crmService instanceof SalesforceInterface) {
/**
* Salesforce support Tasks and Events,
* other crms support only Tasks
*/
$activities = $playbook->activity_type === Playbook::ACTIVITY_TYPE_TASK
? $crmService->getTasks($objectType, $objectId, $opportunityId)
: $crmService->getEvents($objectType, $objectId, $opportunityId);
} else {
$activities = $crmService->getTasks($objectType, $objectId, $opportunityId);
}
} catch (\InvalidArgumentException $exception) {
return $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException $exception) {
return $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
return $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
return $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return [
'activities' => $activities,
'playbookActivityType' => $playbook->activity_type,
];
}
/**
* Method for retrieving remote customer details.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function customers(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
$crmProvider = $team->crm->provider;
$request->validate([
'objectType' => 'in:lead,contact,account,opportunity,undefined',
'providerId' => new CrmReference($crmProvider),
'phoneNumber' => 'phone:INTERNATIONAL,US,' . $user->country_code,
]);
$objectType = $request->input('objectType');
$objectId = $request->input('providerId');
$phoneNumber = $request->input('phoneNumber');
$this->response
->getManager()
->setSerializer(new JsonSerializer());
try {
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($objectId) {
if (($objectType === null || $objectType === 'undefined')
&& $crmService instanceof SupportsObjectTypeParseInterface
) {
$objectType = $crmService->parseObjectType($objectId);
}
switch ($objectType) {
case 'lead':
$lead = $this->getLead($objectId);
$response = $this->response->withItem($lead, new LeadTransformer());
break;
case 'account':
$account = $this->getAccount($objectId);
$response = $this->response->withItem($account, new AccountTransformer());
break;
case 'contact':
$contact = $this->getContact($objectId);
$response = $this->response->withItem($contact, new ContactTransformer());
break;
case 'opportunity':
$opportunity = $this->getOpportunity($objectId);
$response = $this->response->withItem($opportunity->account, new AccountTransformer());
break;
default:
$response = $this->response->errorWrongArgs('Sorry, we don\'t support messaging this type of record.');
break;
}
} elseif ($phoneNumber) {
[$lead, $account, , $contact] = $crmService->matchByPhone(
$phoneNumber,
null,
$user->getId()
);
if ($lead) {
$response = $this->response->withItem($lead, new LeadTransformer());
} elseif ($account) {
$response = $this->response->withItem($account, new AccountTransformer());
} elseif ($contact) {
$response = $this->response->withItem($contact, new ContactTransformer());
} else {
$response = $this->response->errorNotFound('Customer not found.');
}
} else {
$response = $this->response->errorWrongArgs('No search data provided.');
}
} catch (\InvalidArgumentException $exception) {
$response = $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION);
}
return $response;
}
/**
* Rest method for retrieving accounts.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function accounts(): mixed
{
$user = $this->getUserFromRequest($this->request);
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'accountId' => new CrmReference($crmProvider),
]);
$this->response->getManager()->setSerializer(new JsonSerializer());
if ($this->request->has('accountId')) {
$accountId = $this->request->input('accountId');
try {
$account = $this->getAccount($accountId);
$response = $this->response->withItem($account, new AccountTransformer());
} catch (DomainException) {
$response = $this->response->errorNotFound('Record not found.');
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
} else {
$response = $this->response->withCollection($user->team->accounts, new AccountTransformer());
}
return $response;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $accountId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return Account
*/
private function getAccount(string $accountId): Account
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$account = $team->crm->accounts()->where('crm_provider_id', $accountId)->first();
if ($account instanceof Account) {
return $account;
}
// Account does not exist locally, import it.
try {
return $this->getCrmServiceWithActiveUser($user)->syncAccount($accountId);
} catch (SocialAccountTokenInvalidException $exception) {
return $this->response->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.'
);
}
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $opportunityId
*
* @throws DomainException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Opportunity
*/
private function getOpportunity(string $opportunityId): Opportunity
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if (! $opportunity instanceof Opportunity) {
$crmService = $this->getCrmServiceWithActiveUser($user);
$opportunity = $crmService->syncOpportunity($opportunityId);
}
// Sanity check.
if ($user->team_id !== $opportunity->account->team_id) {
throw new DomainException('Opportunity not found.');
}
return $opportunity;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $contactId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Contact
*/
private function getContact(string $contactId): Contact
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$crmService = $this->getCrmServiceWithActiveUser($user);
$contact = $crmService->syncContact($contactId);
}
return $contact;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $leadId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Lead
*/
private function getLead(string $leadId): Lead
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$lead = $team->crm->leads()->where('crm_provider_id', $leadId)->first();
if ($lead instanceof Lead) {
return $lead;
}
// Lead does not exist locally, import it.
return $this->getCrmServiceWithActiveUser($user)->syncLead($leadId);
}
/**
* Rest method for retrieving contacts.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function contacts(): mixed
{
$user = $this->request->user();
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],
'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],
]);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
try {
// Determine if they wish to retrieve a single contact or multiple for an account.
if ($this->request->has('contactId')) {
$contactId = $this->request->input('contactId');
$contact = $this->getContact($contactId);
$response = $this->response->withItem($contact, new ContactTransformer());
} else {
$accountId = $this->request->input('accountId');
$account = $this->getAccount($accountId);
$response = $this->response->withCollection($account->contacts, new ContactTransformer());
}
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
return $response;
}
/**
* Rest method for retrieving leads.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function leads(): mixed
{
$user = $this->request->user();
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'leadId' => new CrmReference($crmProvider),
]);
$this->response
->getManager()
->setSerializer(new JsonSerializer())
->parseIncludes(['stage', 'recordType']);
if ($this->request->has('leadId')) {
$leadId = $this->request->input('leadId');
try {
$lead = $this->getLead($leadId);
$response = $this->response->withItem($lead, new LeadTransformer());
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
} else {
$response = $this->response->withCollection($user->team->leads, new LeadTransformer());
}
return $response;
}
/**
* @param Request $request
*
* @throws ValidationException
*
* @return JsonResponse
*/
public function layouts(Request $request): JsonResponse
{
$request->validate([
'type' => 'required|in:' . implode(',', Layout::$enumTypes),
]);
$user = $request->user();
$type = $request->input('type');
// Take the activity type from the Playbook (default to first for orphaned users).
if ($user->group_id) {
$playbook = $user->group->playbook;
} else {
/** @var Playbook $playbook */
$playbook = $user->team->playbooks()->first();
}
if ($playbook === null) {
return $this->response->errorUnprocessable('Please configure a Playbook first.');
}
$layoutTypeParts = explode('-', $type);
$layoutType = sprintf(
'%s-%s',
reset($layoutTypeParts),
end($layoutTypeParts)
);
/** @var Layout|null $layout */
$layout = $playbook->layouts()
->where('name', ucfirst($playbook->activity_type) . ' Based Layout')
->where('type', $layoutType)
->first();
if ($layout === null) {
return $this->response->errorNotFound('Layout not found.');
}
$this->response
->getManager()
->setSerializer(new JsonSerializer())
->parseIncludes([
'entities.children.field.options',
]);
$transformer = new LayoutTransformer($user->crmProfile)
->setNoDefaultActivityTypeFollowUp(true)
;
return $this->response->withItem($layout, $transformer);
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmServiceWithActiveUser(User $user): ServiceInterface
{
if ($this->crmService === null) {
$team = $user->getTeam();
if (! $user->isCrmRequired()) {
$integrationAdmin = $team->getOwner();
} else {
$integrationAdmin = $user;
}
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $integrationAdmin,
'providerSlug' => $team->getCrmConfiguration()->getProviderName(),
]);
$this->crmService = $crmResolver->prepareCrmService();
}
return $this->crmService;
}
}
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
21
1
18
2
6
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id
where u.team_id = 1;
SELECT * FROM social_accounts WHERE sociable_id = 1635;
SELECT * FROM users WHERE id = 1635;
select * from teams where id = 1;
select * from users where team_id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role;
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
SELECT * FROM automated_reports where id = 71;
SELECT * FROM automated_report_results where report_id = 71;
UPDATE automated_reports set playbook_categories = NULL where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT `automated_report_results`.* FROM `automated_report_results`
INNER JOIN `automated_reports`
ON `automated_report_results`.`report_id` = `automated_reports`.`id`
WHERE 1=1
AND `automated_report_results`.`generated_at` IS NOT NULL
# AND `automated_report_results`.`sent_at` IS NOT NULL
AND `automated_reports`.`team_id` = 1
AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$."users"')
;
SELECT * FROM automated_reports where id = 67;
SELECT * FROM automated_reports where id = 42;
SELECT * FROM users WHERE id = 143; # group 28
select * from teams where id = 3143;
select * from crm_configurations where id = 500;
select * from users where name = 'Integration Account'; # 1695
SELECT * FROM social_accounts WHERE sociable_id = 1695;
select * from activities where crm_configuration_id = 39
and recording_state = 'recorded' and duration > 60
and status = 'completed' and actual_start_time >= '2025-12-01';
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;
select * from leads;
SELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003
SELECT * FROM activities WHERE id IN (16,422003);
SELECT * FROM activities where status = 'failed';
SELECT * FROM tracks WHERE activity_id = 422003;
SELECT
a.*
FROM activities a
JOIN users u ON a.user_id = u.id
WHERE
a.status = 'completed'
AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid
AND a.deleted_at IS NULL
AND EXISTS (
SELECT 1 FROM tracks t
WHERE t.activity_id = a.id
AND t.type IN ('audio', 'video')
)
ORDER BY a.actual_start_time DESC
LIMIT 25;
select * from teams where id = 19;
select * from crm_configurations where provider = 'pipedrive';
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 = 19 and sa.provider = 'pipedrive';
SELECT * FROM social_accounts WHERE id = 1116;
UPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',
provider_refresh_token = '5034113:[TELEGRAM_TOKEN]b2bfc',
expires = 1779091997,
state = 'connected'
WHERE id = 1116;
"provider_user_token": "v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA",
"provider_refresh_token": "5034113:[TELEGRAM_TOKEN]b2bfc",
"expires": 1779091997,
select * from crm_field_values;
select * from crm_fields where type = 'multi-picklist';
SELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
SELECT * FROM crm_fields WHERE id = 3014; # 1885
SELECT * FROM crm_field_values WHERE crm_field_id = 3014;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
79503
|
NULL
|
NULL
|
NULL
|
|
79506
|
2787
|
61
|
2026-05-28T06:32:32.880768+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949952880_m2.jpg...
|
PhpStorm
|
faVsco.js – CrmController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
rnpstomEV faVsco,ls ~ProjectvViewNavigate$2 JY-209 rnpstomEV faVsco,ls ~ProjectvViewNavigate$2 JY-20915-fix-missCoocKelucionTOOI-WindowA console (EU]yboseconto trionooe enktonercondo cionocomposer.json© SyneMailbox.php& Dockerfiieclass CrnController extends Controllersuoure Tuncczon lavours keauest orequeseye ssonkesponssphe api.php© CrmController.phpE env.productionE envowoalto VeirtomonteOUeahxConouon©LanguageController.phpoaoanaoemenon© LiveFeedController.phpeMeeetsonoone© MessageController.phpc) Metadatacontro er ohoC MooileSettinascontro.erC) Momentcontro er ondc oraannationVemoers.conllcletenr hontd setoote€ PartnerController.php© PhoneNumberController.pePiawnsetehottamoha€ PlaylistController.php© ScimController.php© SidekickController.php# SoftphoneController.phpe ssocondoler.onesuoschodoncondo er.one leamaiAutomaudrkonto639# TeamController.php© TeaminsightsController.ph 645eUserConoeon© VocabularyController.php› DAuthCustomerApi>MintemsiO KioskIe [EMAIL]%) AutomatodReporte [EMAIL]© MediaPipelineController.pl 668d Arnaniaatione Controloe nPartnersController.phpeorntiesantraoenhr// Take the activity type fron the Playbook (default to first for orphaned users).if (Suser->group_id) €Splaybook = Suser->group->pLaybook;felse(/x* @vac Playbook Splaybook */Solayoookuserocaoorawooorswoif (Splaybook aa= nulb) "return sthis-sresconse-serrorunorocessaolel messad'Please configure a Playbook first.*);E custom.logSF jiminny@localhost) x 4 HSJocal ([iminny@localhost)A console (PROD]A console (STAGING)TwyAVDA000TeAutosih acrwitiesa23423S236237IIN users u 1.nc->1: ON a.user_id = u.10IEREa.status = 'completed"AND uuid_to_bin('641flacb-1608-42d1-8726-df52979dadBe')) = u.uuidAND a.deleted_at IS NULLANDSXTESSELECT 1 FROM tracks tWHERE t.activity_id = a.idAND t.type IN ('audio', "video')IDER BY a.actuol_start_time DESC24sNIT 25;Savout woeParts = exolodelSTvoe)SlayoutType = sprintfreset (&array: $layoutTypeParts),endo sarray. Stavout voepants/** @xar Layout/null Slayout */Slayout = Splaybook->layputs()operator: ucfirst(Splaybook-›activity_type) . ' Based Layout')"type', $layoutType)—251->firstO:=260if (Slayout === null) (return Sthis->response->errorNotFound(message: 'Layout not found.'):Sthis->response>getManager()->setSerializer(new JsonSerializer())->parseIncludes(temoroesco oretrselorooetonsD):Stransforner = new Lavourtiransfonner susen->corprortlen->setNodefaulaco virytvoezou onlold nodetau tachitytvoeFollowlp: truesSSEGSE68 fminny ~021 41 418 X2 X8 Ailect * fron teans where id = 19;ilect * fron crn_configurations where provider = 'Ripedcive':FLECTCONCAT(u.id, CASE WHEN U.id = t.ouner_id THEN • (onner)' ELSE ** END) AS user_id,U.ehazlSa.xt.ouner_id FROM social_accounts sawusers uon urs sansodaolenIIN teans t 1.n<->1: on t.id = v.tean_idIERE v.tean_id = 19 and sa.provider = 'pipedrive":FLECT * FROM social_accounts WHERE id = 1116;"DATE social_accounts SET provider_user_token = 'VIu:AQIBAHJ-L2TNK2yuuuaLq{fzhWb9crUNKTpk4FLQ9гjnXqp_6AEQh0hDQVa1nV#CHEvnpvS)1ERE 1031516'provider_user_token": "vlu:AQIBAHJ-LzTNK2yuuuaLgifzhHb9crUNKTpk«F1Q9rjnXqp_6AEQhDhDQVa1nv#CHEvnpvSEAAAAfjB8Bgkqhki69w9BBw35ilect * fron crn field values:ilect * fron crn_fields where type = 'nulti-picklist';ÉLECT * FROM crn_Layouts WHERE uuid_to_bin('7C327871-fc25-4c56-9a0f-44c5a849d6Sc') = uuid;ELECT * FROM crn_layout_entities WHERE crn_layout_id = 282;LECT * FROM Crn_fields WHERE 1d = 3014; # 1885ELECT * FROM crn_field_vatues WHERE crn_field_id = 3014;00%LXThu 28 May 9:32:32U TextRelayServiceTest~aer henseict+0.can I test it locally first. if I place env from stagingYes. The service relies on a few things you'd need in place:1. Credentials file The constructor expects storage/text-relay.son (a Google service account JSON key file)Gmbtrom sthaind and olace it there2. .env values to copy from stagingGOOGLE TEXTUSERECOOGLE TEXTI HASTGOOGLE_TEXT_RELAY_TOPIC=DEPLOY _REGION=the cnail nailbox address# e.g. txt.jiminny.com or txt.staging.jiminny.com# the Pub/Sub topie name* eu or us3. Run the sync manually via tinker (inside docker_lanp_1):D bashdocker exec -it docker_lamp_1 php artisan tinker• 0app(\Jininny\ServicesVMail\TextRelayService::class)->sync();Caveat: The service reads from Gmail history and dispatches jobs to the queue. If you don't want it to actuallsend SMS, make sure QUEUE_CONNECTICN-sync is not set (or use a test queue), or just call isForCurrentEnvironmtioh.Ssvc = new class extends \JiminnylServicesVa1l\TextRelayService ( public function _constructlsom Serviceassvc-soctServicelcontiatainny.googletextI then sinsoect au eessade canuai. 1sasg = SgnaitService-susers_gessages-sget(config(*Jiainny-9009le_text_user*), "THE_MESSAGE_ID*)collect (Sasg->getPayload()-»getHeaders())->pluck("value',thut wey von can Mrity whht handare tra nehhilm oraeset do ttat mactsod alote tha uill evoc rineAsk anything (XOL)- @ eodeAdhotv*throws contesinersxcen toninterdocswwhnoweworsound.yranttantnsanharMectardavlModturlhsme okhires2 4 space:...
|
NULL
|
-668259818853157217
|
NULL
|
click
|
ocr
|
NULL
|
rnpstomEV faVsco,ls ~ProjectvViewNavigate$2 JY-209 rnpstomEV faVsco,ls ~ProjectvViewNavigate$2 JY-20915-fix-missCoocKelucionTOOI-WindowA console (EU]yboseconto trionooe enktonercondo cionocomposer.json© SyneMailbox.php& Dockerfiieclass CrnController extends Controllersuoure Tuncczon lavours keauest orequeseye ssonkesponssphe api.php© CrmController.phpE env.productionE envowoalto VeirtomonteOUeahxConouon©LanguageController.phpoaoanaoemenon© LiveFeedController.phpeMeeetsonoone© MessageController.phpc) Metadatacontro er ohoC MooileSettinascontro.erC) Momentcontro er ondc oraannationVemoers.conllcletenr hontd setoote€ PartnerController.php© PhoneNumberController.pePiawnsetehottamoha€ PlaylistController.php© ScimController.php© SidekickController.php# SoftphoneController.phpe ssocondoler.onesuoschodoncondo er.one leamaiAutomaudrkonto639# TeamController.php© TeaminsightsController.ph 645eUserConoeon© VocabularyController.php› DAuthCustomerApi>MintemsiO KioskIe [EMAIL]%) AutomatodReporte [EMAIL]© MediaPipelineController.pl 668d Arnaniaatione Controloe nPartnersController.phpeorntiesantraoenhr// Take the activity type fron the Playbook (default to first for orphaned users).if (Suser->group_id) €Splaybook = Suser->group->pLaybook;felse(/x* @vac Playbook Splaybook */Solayoookuserocaoorawooorswoif (Splaybook aa= nulb) "return sthis-sresconse-serrorunorocessaolel messad'Please configure a Playbook first.*);E custom.logSF jiminny@localhost) x 4 HSJocal ([iminny@localhost)A console (PROD]A console (STAGING)TwyAVDA000TeAutosih acrwitiesa23423S236237IIN users u 1.nc->1: ON a.user_id = u.10IEREa.status = 'completed"AND uuid_to_bin('641flacb-1608-42d1-8726-df52979dadBe')) = u.uuidAND a.deleted_at IS NULLANDSXTESSELECT 1 FROM tracks tWHERE t.activity_id = a.idAND t.type IN ('audio', "video')IDER BY a.actuol_start_time DESC24sNIT 25;Savout woeParts = exolodelSTvoe)SlayoutType = sprintfreset (&array: $layoutTypeParts),endo sarray. Stavout voepants/** @xar Layout/null Slayout */Slayout = Splaybook->layputs()operator: ucfirst(Splaybook-›activity_type) . ' Based Layout')"type', $layoutType)—251->firstO:=260if (Slayout === null) (return Sthis->response->errorNotFound(message: 'Layout not found.'):Sthis->response>getManager()->setSerializer(new JsonSerializer())->parseIncludes(temoroesco oretrselorooetonsD):Stransforner = new Lavourtiransfonner susen->corprortlen->setNodefaulaco virytvoezou onlold nodetau tachitytvoeFollowlp: truesSSEGSE68 fminny ~021 41 418 X2 X8 Ailect * fron teans where id = 19;ilect * fron crn_configurations where provider = 'Ripedcive':FLECTCONCAT(u.id, CASE WHEN U.id = t.ouner_id THEN • (onner)' ELSE ** END) AS user_id,U.ehazlSa.xt.ouner_id FROM social_accounts sawusers uon urs sansodaolenIIN teans t 1.n<->1: on t.id = v.tean_idIERE v.tean_id = 19 and sa.provider = 'pipedrive":FLECT * FROM social_accounts WHERE id = 1116;"DATE social_accounts SET provider_user_token = 'VIu:AQIBAHJ-L2TNK2yuuuaLq{fzhWb9crUNKTpk4FLQ9гjnXqp_6AEQh0hDQVa1nV#CHEvnpvS)1ERE 1031516'provider_user_token": "vlu:AQIBAHJ-LzTNK2yuuuaLgifzhHb9crUNKTpk«F1Q9rjnXqp_6AEQhDhDQVa1nv#CHEvnpvSEAAAAfjB8Bgkqhki69w9BBw35ilect * fron crn field values:ilect * fron crn_fields where type = 'nulti-picklist';ÉLECT * FROM crn_Layouts WHERE uuid_to_bin('7C327871-fc25-4c56-9a0f-44c5a849d6Sc') = uuid;ELECT * FROM crn_layout_entities WHERE crn_layout_id = 282;LECT * FROM Crn_fields WHERE 1d = 3014; # 1885ELECT * FROM crn_field_vatues WHERE crn_field_id = 3014;00%LXThu 28 May 9:32:32U TextRelayServiceTest~aer henseict+0.can I test it locally first. if I place env from stagingYes. The service relies on a few things you'd need in place:1. Credentials file The constructor expects storage/text-relay.son (a Google service account JSON key file)Gmbtrom sthaind and olace it there2. .env values to copy from stagingGOOGLE TEXTUSERECOOGLE TEXTI HASTGOOGLE_TEXT_RELAY_TOPIC=DEPLOY _REGION=the cnail nailbox address# e.g. txt.jiminny.com or txt.staging.jiminny.com# the Pub/Sub topie name* eu or us3. Run the sync manually via tinker (inside docker_lanp_1):D bashdocker exec -it docker_lamp_1 php artisan tinker• 0app(\Jininny\ServicesVMail\TextRelayService::class)->sync();Caveat: The service reads from Gmail history and dispatches jobs to the queue. If you don't want it to actuallsend SMS, make sure QUEUE_CONNECTICN-sync is not set (or use a test queue), or just call isForCurrentEnvironmtioh.Ssvc = new class extends \JiminnylServicesVa1l\TextRelayService ( public function _constructlsom Serviceassvc-soctServicelcontiatainny.googletextI then sinsoect au eessade canuai. 1sasg = SgnaitService-susers_gessages-sget(config(*Jiainny-9009le_text_user*), "THE_MESSAGE_ID*)collect (Sasg->getPayload()-»getHeaders())->pluck("value',thut wey von can Mrity whht handare tra nehhilm oraeset do ttat mactsod alote tha uill evoc rineAsk anything (XOL)- @ eodeAdhotv*throws contesinersxcen toninterdocswwhnoweworsound.yranttantnsanharMectardavlModturlhsme okhires2 4 space:...
|
79504
|
NULL
|
NULL
|
NULL
|
|
79504
|
2787
|
60
|
2026-05-28T06:32:12.460832+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949932460_m2.jpg...
|
PhpStorm
|
faVsco.js – CrmController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09740692,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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.8374335,"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":"TextRelayServiceTest","depth":6,"bounds":{"left":0.85272604,"top":0.019952115,"width":0.062832445,"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 'TextRelayServiceTest'","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 'TextRelayServiceTest'","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}]...
|
7923424182753190895
|
-8780372176425246254
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
rnpstomViewNeWENNCCoocKelucionRurToolWindowFV faVsco.|s ~proidet$ JY-20915-fix-missa Kemnelonip© SyncMailbox.phpyboseconto trionocomposer.jsonDockerfileTextRelayServiceTest.phooe enktonercondo cionoemconto tronoclass CraController extends Controllenpublic functionLeads): mixedt...;owoalto VeirtomonteOUeahxConouon© LanquaceController.ohooaoanaoemenonC LiveFeedController.ohoeMeeetsonoonec) Messagecontro er ohoc) Metadatacontro er oho609© Mobile Settingscontroller.$ 616C) Momentcontro er.ondc Nudgecontro ec ond613613lcletenr hontd setootetaparnweoatrolineoo.© PhoneNumberController.p(C PlaybackController.phpeDiaviietshatrailae nhn© ScimController.php© SidekickController.php© SoftphoneController.phpe ssocondoler.onesuoschodoncondo er.one leamsiautomaudkontoe) TosmAlGAntovGAntrAlor4 Toam Controller, oholTeaminsightsController.ph©TranscriptionController.ph 632© TranslationController.oho©UserController.ohdf VocabularyController.oho>MAuth>McustomerAo>Mintemsi@ KioskIe Teame8989© ActivityController.php%) AutomatodReporte Controlcbachbaard eontroe.ondclimoerconationControeo@ MediaPioelineController.pl@ AraaniaationeControloend DortnoreContralor nhoci oratiesantraioe nhr* Boacan Request Srequest* ethrows ValidationException* Preturn JsonResponsepublic function layouts(Request Srequest): JsonResponseSrequest->vaLidateco"type" => 'requiredlin:' . inplode( separator: ".". Layout:: SenunTupes)Suser = Sreguest->userO:SwoereOUeso No newI Take the activity type fron the Playbook (default to first for orohaned users)Suser-saroupo)Splaybook = Suser-saroup->olaybook;}else "/** Bvac Playbook Splaybook */Solavbook = Suser->tear->olavbooks oe>einstonSolaybook =a= nulonetuonrhisesnasnansa.sancoclioonocaccaoilelt messnogpleace contsaune aplauhook finst.!Miavoutiunspante = ayailadat coonate)Stayouttype = sprintfureset ( Garray: $layoutTypeParts),end ( Garray: $layoutTypeParts)/** Svac Layout/null $layout */Slavout = Splaybook->lavoutsooperator ucfirst(Splaybook-›activity_type) • ' Based Layout')avouievioeSif (Slavout === null) freturn Sthis->response-sercorNotFound( messaoe: "Lavout not found,")Sthis->responseootharanousoneMactarcay.50lphe api.phg© CrmController.phpSF (iminny@localhost) xconedia PereA console (EU)Fm tuons.env.production₴.envAA8V9AVA console (STAGING]D000€TeAutosPOM activitales &IIN users u 1.nc->1: ON a.user_id = u.icTEREDo jminny23S236_238— 241|259=260270273021 A1 A18 V2 Y6 Aa.status ='completedAno uurd co bind 6411800-1608-4201-8726-4757079da08eD = u.uusdAND a.deleted_at IS NULLANDSXTESSELECT 1 FROM tracks tAND t.type IN ('audio', "video"IDER BY a.actual_start_time DESOMIT 25;ilect * fron teans where id = 19:ilect * fron crn configurations where provider = 'pipedrive'ELECTCONCAT(u.id, CASE WHEN u.id = t.ouner id THEN " (ouner)' ELSE ** END) AS user idv.enailSa.xthouner1d FROM socilal accounts s:JN users u on unid = sa,sociable ioJTN teans t 1.nc-›1: on t5id = u.team 1dlJERE u,tean 1d = 19 and sa,onoyiden = "oipedoive':SLECT * FROM social accounts WHERE 1d = 1116%DATE sochal accounte SET onowiden usen token = *VAu:AOTBAHS-L2TNK2yuuuaLo1f2hWb9ccUNKTok4F109cinXoo 6AE0h0h00Va1nvalCHEynovS)1ERE 1031516provider_user-token": "viu:AQLBAH5-L2/NK2yuuuaLqifzh#b9crUNKtpk4F109minXap_6AE0hDhD0Va1nviCHEvnpvSEAAAAf:1888gkqhk169w8BBwcgMont &tmn en old vahuoc)ilect * fron crm fields where type = 'nulti-picklist':LECT * FROM Crn_ Layouts WHERE uuid_to_bin(*7C327871-4c25-4c56-9a0f-44c5a849d65c') = uuid;ELECT * FROM crm layout entities WHERE crn layout id = 282:ELECT * FROM crn fields WHERE id = 3014; # 1889ELECT * FROM crn field values WHERE crn field id = 381400%LXThu 28 May 9:32:12TextRelayServiceTestaer henseict+0.can I test it locally first. if I place env from stagingYes. The service relies on a tew thinas vou'd need in place1. Credentials file The constructor expects storage/text-relay.ison (a Google service account JSON key file)Gmbtrom sthaind and oince it there2. .env values to copy from stagingGOOGLE TEXTUSERECOOGLE TEXTI HASTGOOGLE TEXT RELAY TOPIC:DEPLOY REGION:the cnail mailbox address# e.g. txt.jiminny.com or txt.staging.jiminny.com# the Pub/Sub topic namaeu or us3. Run the svnc manuallv vin tinker tinside docker 1aeo 10%b bashaegdocker exec -it docker_lamp_1 php artisan tinkeapp(\Jiminny\Services\Ma1l\TextRelayService::class)-sync():Caveat: The service reads from Gmail history and dispatches jobs to the queue. If you don't want it to actuallsend SMS, make sure QUEUE_CONNECTICN»sync is not set (or use a test queue), or just call isForCurrentEnvironntioh.Ssvc = new class extends \Jiminny\Services\Mail\TextRelayService & public function _construct(som Serviceassvc-soctServicelcontiatainny.googletextI then sinsoect au eessade canuai. 1sasg= sonailService-susers_messages-sget(config(*iminty.google text user'), *THE_MESSAGE ID')collect(5-s0-20etPayload()-soetWeaders())-soluck("value"thut wey von can Mrit whht nandore tra nenhily oraeaet do htas macesod Calora tha ull evoc nineAsk anything (%OL)- @ eodeAdhotvXModturTasme Foo.rowhies*4 space...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79503
|
2786
|
35
|
2026-05-28T06:32:12.273966+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949932273_m1.jpg...
|
PhpStorm
|
faVsco.js – CrmController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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":"TextRelayServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-4060176888399009113
|
-9212323791225028208
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV (docker)₴2-zshscreenpipe"Fixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated.Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration"is deprecated.Use "@PHP8x0Migration"instead.Rule set "@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-iM.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206masterce9abde868..3800efb7ea JY-20905-tool-search-members-> origin/iorigin/.ad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss*Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-HomeDMsActivityFilesLaterMore+ED→Jiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...° Direct messages&. Petko Kashinskião Stefka Stoyanova:Todor StamatovSteliyan GeorgievVes% MiraP. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y... O::: Appsã Jira CloudToast100% <Thu 28 May 9:32:12Describe what you are looking forPetko Kashinski6 0Messagest Add canvas@ FilesLukas Kova'**Tuesday, May 12th ~добро утро+Петко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, но 'MultiPicklist' type, a нe single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастихм, не сьм сигуренще проверяMessage Petko Kashinski+...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79502
|
2786
|
34
|
2026-05-28T06:32:08.054662+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949928054_m1.jpg...
|
PhpStorm
|
faVsco.js – CrmController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
48
9
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use DomainException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Jiminny\Contracts\Services\Crm\Provider\SalesforceInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\ServiceUnavailableException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\AccountTransformer;
use Jiminny\Http\Transformers\ContactTransformer;
use Jiminny\Http\Transformers\LayoutTransformer;
use Jiminny\Http\Transformers\LeadTransformer;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Models\Account;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Playbook;
use Jiminny\Models\User;
use Jiminny\Rules\CrmReference;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class CrmController extends Controller
{
private const string MESSAGE_GENERAL_EXCEPTION_SEARCHING = 'Sorry, an internal error occurred whilst searching.';
private const string MESSAGE_GENERAL_EXCEPTION = 'Sorry, an internal error occurred.';
private ?ServiceInterface $crmService = null;
public function __construct(Response $response)
{
parent::__construct($response);
}
/**
* Method for searching for remote records by name.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function search(Request $request): mixed
{
$allowedScopes = [
'lead',
'account',
'contact',
'account-business',
'account-person',
'contact-business',
'contact-person',
];
$request->validate([
'scopes' => 'required|in:' . implode(',', $allowedScopes) . '|array',
'name' => 'required|string|max:100|min:2',
'limit' => 'min:1|max:20',
'offset' => 'min:0',
]);
$scopes = $request->input('scopes');
$name = $request->input('name');
$limit = $request->input('limit', 20);
$offset = $request->input('offset', 0);
$user = $this->getUserFromRequest($request);
try {
$crmService = $this->getCrmServiceWithActiveUser($user);
$crmService->setPage($limit, $offset);
$response = $crmService->find($name, $scopes);
} catch (SocialAccountTokenInvalidException $exception) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (CrmException $exception) {
$response = [];
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return $response;
}
/**
* Method for retrieving remote opportunities by account or contact.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function opportunities(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
try {
$crmProvider = $team->crm->provider;
$request->validate([
'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],
'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],
]);
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($this->request->has('contactId')) {
$contactId = $this->request->input('contactId');
$contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();
// Contact does not exist locally, import it.
if ($contact === null) {
$contact = $crmService->syncContact($contactId);
}
$accountId = $contact->account_id ? $contact->account->crm_provider_id : null;
} else {
$contactId = null;
$accountId = $this->request->input('accountId');
}
$response = $crmService->findOpportunities($accountId, $contactId, $user->getId());
} catch (\InvalidArgumentException $exception) {
$response = $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException $exception) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return $response;
}
/**
* Method for retrieving remote tasks by user.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function activities(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
$crmProvider = $team->crm->provider;
$request->validate([
'objectType' => 'in:lead,contact,account',
'prospectId' => new CrmReference($crmProvider),
'opportunityId' => new CrmReference($crmProvider),
]);
try {
$opportunityId = $request->input('opportunityId');
$objectType = $request->input('objectType');
$objectId = $request->input('prospectId');
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($objectType === null
&& $crmService instanceof SupportsObjectTypeParseInterface
) {
$objectType = $crmService->parseObjectType($objectId);
}
// Take the activity type from the Playbook (default to first for orphaned users).
if ($user->group_id) {
$playbook = $user->group->playbook;
} else {
$playbook = $user->team->playbooks()->first();
// fix empty playbook
if ($playbook === null) {
throw new \InvalidArgumentException('Please configure a Playbook first.');
}
}
if ($crmService instanceof SalesforceInterface) {
/**
* Salesforce support Tasks and Events,
* other crms support only Tasks
*/
$activities = $playbook->activity_type === Playbook::ACTIVITY_TYPE_TASK
? $crmService->getTasks($objectType, $objectId, $opportunityId)
: $crmService->getEvents($objectType, $objectId, $opportunityId);
} else {
$activities = $crmService->getTasks($objectType, $objectId, $opportunityId);
}
} catch (\InvalidArgumentException $exception) {
return $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException $exception) {
return $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
return $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
return $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return [
'activities' => $activities,
'playbookActivityType' => $playbook->activity_type,
];
}
/**
* Method for retrieving remote customer details.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function customers(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
$crmProvider = $team->crm->provider;
$request->validate([
'objectType' => 'in:lead,contact,account,opportunity,undefined',
'providerId' => new CrmReference($crmProvider),
'phoneNumber' => 'phone:INTERNATIONAL,US,' . $user->country_code,
]);
$objectType = $request->input('objectType');
$objectId = $request->input('providerId');
$phoneNumber = $request->input('phoneNumber');
$this->response
->getManager()
->setSerializer(new JsonSerializer());
try {
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($objectId) {
if (($objectType === null || $objectType === 'undefined')
&& $crmService instanceof SupportsObjectTypeParseInterface
) {
$objectType = $crmService->parseObjectType($objectId);
}
switch ($objectType) {
case 'lead':
$lead = $this->getLead($objectId);
$response = $this->response->withItem($lead, new LeadTransformer());
break;
case 'account':
$account = $this->getAccount($objectId);
$response = $this->response->withItem($account, new AccountTransformer());
break;
case 'contact':
$contact = $this->getContact($objectId);
$response = $this->response->withItem($contact, new ContactTransformer());
break;
case 'opportunity':
$opportunity = $this->getOpportunity($objectId);
$response = $this->response->withItem($opportunity->account, new AccountTransformer());
break;
default:
$response = $this->response->errorWrongArgs('Sorry, we don\'t support messaging this type of record.');
break;
}
} elseif ($phoneNumber) {
[$lead, $account, , $contact] = $crmService->matchByPhone(
$phoneNumber,
null,
$user->getId()
);
if ($lead) {
$response = $this->response->withItem($lead, new LeadTransformer());
} elseif ($account) {
$response = $this->response->withItem($account, new AccountTransformer());
} elseif ($contact) {
$response = $this->response->withItem($contact, new ContactTransformer());
} else {
$response = $this->response->errorNotFound('Customer not found.');
}
} else {
$response = $this->response->errorWrongArgs('No search data provided.');
}
} catch (\InvalidArgumentException $exception) {
$response = $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION);
}
return $response;
}
/**
* Rest method for retrieving accounts.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function accounts(): mixed
{
$user = $this->getUserFromRequest($this->request);
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'accountId' => new CrmReference($crmProvider),
]);
$this->response->getManager()->setSerializer(new JsonSerializer());
if ($this->request->has('accountId')) {
$accountId = $this->request->input('accountId');
try {
$account = $this->getAccount($accountId);
$response = $this->response->withItem($account, new AccountTransformer());
} catch (DomainException) {
$response = $this->response->errorNotFound('Record not found.');
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
} else {
$response = $this->response->withCollection($user->team->accounts, new AccountTransformer());
}
return $response;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $accountId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return Account
*/
private function getAccount(string $accountId): Account
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$account = $team->crm->accounts()->where('crm_provider_id', $accountId)->first();
if ($account instanceof Account) {
return $account;
}
// Account does not exist locally, import it.
try {
return $this->getCrmServiceWithActiveUser($user)->syncAccount($accountId);
} catch (SocialAccountTokenInvalidException $exception) {
return $this->response->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.'
);
}
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $opportunityId
*
* @throws DomainException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Opportunity
*/
private function getOpportunity(string $opportunityId): Opportunity
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if (! $opportunity instanceof Opportunity) {
$crmService = $this->getCrmServiceWithActiveUser($user);
$opportunity = $crmService->syncOpportunity($opportunityId);
}
// Sanity check.
if ($user->team_id !== $opportunity->account->team_id) {
throw new DomainException('Opportunity not found.');
}
return $opportunity;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $contactId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Contact
*/
private function getContact(string $contactId): Contact
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$crmService = $this->getCrmServiceWithActiveUser($user);
$contact = $crmService->syncContact($contactId);
}
return $contact;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $leadId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Lead
*/
private function getLead(string $leadId): Lead
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$lead = $team->crm->leads()->where('crm_provider_id', $leadId)->first();
if ($lead instanceof Lead) {
return $lead;
}
// Lead does not exist locally, import it.
return $this->getCrmServiceWithActiveUser($user)->syncLead($leadId);
}
/**
* Rest method for retrieving contacts.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function contacts(): mixed
{
$user = $this->request->user();
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],
'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],
]);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
try {
// Determine if they wish to retrieve a single contact or multiple for an account.
if ($this->request->has('contactId')) {
$contactId = $this->request->input('contactId');
$contact = $this->getContact($contactId);
$response = $this->response->withItem($contact, new ContactTransformer());
} else {
$accountId = $this->request->input('accountId');
$account = $this->getAccount($accountId);
$response = $this->response->withCollection($account->contacts, new ContactTransformer());
}
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
return $response;
}
/**
* Rest method for retrieving leads.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function leads(): mixed
{
$user = $this->request->user();
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'leadId' => new CrmReference($crmProvider),
]);
$this->response
->getManager()
->setSerializer(new JsonSerializer())
->parseIncludes(['stage', 'recordType']);
if ($this->request->has('leadId')) {
$leadId = $this->request->input('leadId');
try {
$lead = $this->getLead($leadId);
$response = $this->response->withItem($lead, new LeadTransformer());
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
} else {
$response = $this->response->withCollection($user->team->leads, new LeadTransformer());
}
return $response;
}
/**
* @param Request $request
*
* @throws ValidationException
*
* @return JsonResponse
*/
public function layouts(Request $request): JsonResponse
{
$request->validate([
'type' => 'required|in:' . implode(',', Layout::$enumTypes),
]);
$user = $request->user();
$type = $request->input('type');
// Take the activity type from the Playbook (default to first for orphaned users).
if ($user->group_id) {
$playbook = $user->group->playbook;
} else {
/** @var Playbook $playbook */
$playbook = $user->team->playbooks()->first();
}
if ($playbook === null) {
return $this->response->errorUnprocessable('Please configure a Playbook first.');
}
$layoutTypeParts = explode('-', $type);
$layoutType = sprintf(
'%s-%s',
reset($layoutTypeParts),
end($layoutTypeParts)
);
/** @var Layout|null $layout */
$layout = $playbook->layouts()
->where('name', ucfirst($playbook->activity_type) . ' Based Layout')
->where('type', $layoutType)
->first();
if ($layout === null) {
return $this->response->errorNotFound('Layout not found.');
}
$this->response
->getManager()
->setSerializer(new JsonSerializer())
->parseIncludes([
'entities.children.field.options',
]);
$transformer = new LayoutTransformer($user->crmProfile)
->setNoDefaultActivityTypeFollowUp(true)
;
return $this->response->withItem($layout, $transformer);
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmServiceWithActiveUser(User $user): ServiceInterface
{
if ($this->crmService === null) {
$team = $user->getTeam();
if (! $user->isCrmRequired()) {
$integrationAdmin = $team->getOwner();
} else {
$integrationAdmin = $user;
}
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $integrationAdmin,
'providerSlug' => $team->getCrmConfiguration()->getProviderName(),
]);
$this->crmService = $crmResolver->prepareCrmService();
}
return $this->crmService;
}
}
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
21
1
18
2
6
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id
where u.team_id = 1;
SELECT * FROM social_accounts WHERE sociable_id = 1635;
SELECT * FROM users WHERE id = 1635;
select * from teams where id = 1;
select * from users where team_id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role;
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
SELECT * FROM automated_reports where id = 71;
SELECT * FROM automated_report_results where report_id = 71;
UPDATE automated_reports set playbook_categories = NULL where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT `automated_report_results`.* FROM `automated_report_results`
INNER JOIN `automated_reports`
ON `automated_report_results`.`report_id` = `automated_reports`.`id`
WHERE 1=1
AND `automated_report_results`.`generated_at` IS NOT NULL
# AND `automated_report_results`.`sent_at` IS NOT NULL
AND `automated_reports`.`team_id` = 1
AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$."users"')
;
SELECT * FROM automated_reports where id = 67;
SELECT * FROM automated_reports where id = 42;
SELECT * FROM users WHERE id = 143; # group 28
select * from teams where id = 3143;
select * from crm_configurations where id = 500;
select * from users where name = 'Integration Account'; # 1695
SELECT * FROM social_accounts WHERE sociable_id = 1695;
select * from activities where crm_configuration_id = 39
and recording_state = 'recorded' and duration > 60
and status = 'completed' and actual_start_time >= '2025-12-01';
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;
select * from leads;
SELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003
SELECT * FROM activities WHERE id IN (16,422003);
SELECT * FROM activities where status = 'failed';
SELECT * FROM tracks WHERE activity_id = 422003;
SELECT
a.*
FROM activities a
JOIN users u ON a.user_id = u.id
WHERE
a.status = 'completed'
AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid
AND a.deleted_at IS NULL
AND EXISTS (
SELECT 1 FROM tracks t
WHERE t.activity_id = a.id
AND t.type IN ('audio', 'video')
)
ORDER BY a.actual_start_time DESC
LIMIT 25;
select * from teams where id = 19;
select * from crm_configurations where provider = 'pipedrive';
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 = 19 and sa.provider = 'pipedrive';
SELECT * FROM social_accounts WHERE id = 1116;
UPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',
provider_refresh_token = '5034113:[TELEGRAM_TOKEN]b2bfc',
expires = 1779091997,
state = 'connected'
WHERE id = 1116;
"provider_user_token": "v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA",
"provider_refresh_token": "5034113:[TELEGRAM_TOKEN]b2bfc",
"expires": 1779091997,
select * from crm_field_values;
select * from crm_fields where type = 'multi-picklist';
SELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
SELECT * FROM crm_fields WHERE id = 3014; # 1885
SELECT * FROM crm_field_values WHERE crm_field_id = 3014;
Project
Project...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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":"TextRelayServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'TextRelayServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'TextRelayServiceTest'","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":"48","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"9","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse DomainException;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\SalesforceInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\ServiceUnavailableException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\AccountTransformer;\nuse Jiminny\\Http\\Transformers\\ContactTransformer;\nuse Jiminny\\Http\\Transformers\\LayoutTransformer;\nuse Jiminny\\Http\\Transformers\\LeadTransformer;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass CrmController extends Controller\n{\n private const string MESSAGE_GENERAL_EXCEPTION_SEARCHING = 'Sorry, an internal error occurred whilst searching.';\n private const string MESSAGE_GENERAL_EXCEPTION = 'Sorry, an internal error occurred.';\n private ?ServiceInterface $crmService = null;\n\n public function __construct(Response $response)\n {\n parent::__construct($response);\n }\n\n /**\n * Method for searching for remote records by name.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function search(Request $request): mixed\n {\n $allowedScopes = [\n 'lead',\n 'account',\n 'contact',\n 'account-business',\n 'account-person',\n 'contact-business',\n 'contact-person',\n ];\n\n $request->validate([\n 'scopes' => 'required|in:' . implode(',', $allowedScopes) . '|array',\n 'name' => 'required|string|max:100|min:2',\n 'limit' => 'min:1|max:20',\n 'offset' => 'min:0',\n ]);\n\n $scopes = $request->input('scopes');\n $name = $request->input('name');\n $limit = $request->input('limit', 20);\n $offset = $request->input('offset', 0);\n $user = $this->getUserFromRequest($request);\n\n try {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n $crmService->setPage($limit, $offset);\n\n $response = $crmService->find($name, $scopes);\n } catch (SocialAccountTokenInvalidException $exception) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (CrmException $exception) {\n $response = [];\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return $response;\n }\n\n /**\n * Method for retrieving remote opportunities by account or contact.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function opportunities(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n\n try {\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],\n 'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],\n ]);\n\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($this->request->has('contactId')) {\n $contactId = $this->request->input('contactId');\n\n $contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();\n\n // Contact does not exist locally, import it.\n if ($contact === null) {\n $contact = $crmService->syncContact($contactId);\n }\n\n $accountId = $contact->account_id ? $contact->account->crm_provider_id : null;\n } else {\n $contactId = null;\n $accountId = $this->request->input('accountId');\n }\n\n $response = $crmService->findOpportunities($accountId, $contactId, $user->getId());\n } catch (\\InvalidArgumentException $exception) {\n $response = $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException $exception) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return $response;\n }\n\n /**\n * Method for retrieving remote tasks by user.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function activities(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'objectType' => 'in:lead,contact,account',\n 'prospectId' => new CrmReference($crmProvider),\n 'opportunityId' => new CrmReference($crmProvider),\n ]);\n\n try {\n $opportunityId = $request->input('opportunityId');\n $objectType = $request->input('objectType');\n $objectId = $request->input('prospectId');\n\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($objectType === null\n && $crmService instanceof SupportsObjectTypeParseInterface\n ) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n\n // Take the activity type from the Playbook (default to first for orphaned users).\n if ($user->group_id) {\n $playbook = $user->group->playbook;\n } else {\n $playbook = $user->team->playbooks()->first();\n\n // fix empty playbook\n if ($playbook === null) {\n throw new \\InvalidArgumentException('Please configure a Playbook first.');\n }\n }\n\n if ($crmService instanceof SalesforceInterface) {\n /**\n * Salesforce support Tasks and Events,\n * other crms support only Tasks\n */\n $activities = $playbook->activity_type === Playbook::ACTIVITY_TYPE_TASK\n ? $crmService->getTasks($objectType, $objectId, $opportunityId)\n : $crmService->getEvents($objectType, $objectId, $opportunityId);\n } else {\n $activities = $crmService->getTasks($objectType, $objectId, $opportunityId);\n }\n } catch (\\InvalidArgumentException $exception) {\n return $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException $exception) {\n return $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n return $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n\n return $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return [\n 'activities' => $activities,\n 'playbookActivityType' => $playbook->activity_type,\n ];\n }\n\n /**\n * Method for retrieving remote customer details.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function customers(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'objectType' => 'in:lead,contact,account,opportunity,undefined',\n 'providerId' => new CrmReference($crmProvider),\n 'phoneNumber' => 'phone:INTERNATIONAL,US,' . $user->country_code,\n ]);\n\n $objectType = $request->input('objectType');\n $objectId = $request->input('providerId');\n $phoneNumber = $request->input('phoneNumber');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n try {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($objectId) {\n if (($objectType === null || $objectType === 'undefined')\n && $crmService instanceof SupportsObjectTypeParseInterface\n ) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n\n switch ($objectType) {\n case 'lead':\n $lead = $this->getLead($objectId);\n $response = $this->response->withItem($lead, new LeadTransformer());\n\n break;\n\n case 'account':\n $account = $this->getAccount($objectId);\n $response = $this->response->withItem($account, new AccountTransformer());\n\n break;\n\n case 'contact':\n $contact = $this->getContact($objectId);\n $response = $this->response->withItem($contact, new ContactTransformer());\n\n break;\n\n case 'opportunity':\n $opportunity = $this->getOpportunity($objectId);\n $response = $this->response->withItem($opportunity->account, new AccountTransformer());\n\n break;\n\n default:\n $response = $this->response->errorWrongArgs('Sorry, we don\\'t support messaging this type of record.');\n\n break;\n }\n } elseif ($phoneNumber) {\n [$lead, $account, , $contact] = $crmService->matchByPhone(\n $phoneNumber,\n null,\n $user->getId()\n );\n\n if ($lead) {\n $response = $this->response->withItem($lead, new LeadTransformer());\n } elseif ($account) {\n $response = $this->response->withItem($account, new AccountTransformer());\n } elseif ($contact) {\n $response = $this->response->withItem($contact, new ContactTransformer());\n } else {\n $response = $this->response->errorNotFound('Customer not found.');\n }\n } else {\n $response = $this->response->errorWrongArgs('No search data provided.');\n }\n } catch (\\InvalidArgumentException $exception) {\n $response = $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION);\n }\n\n return $response;\n }\n\n /**\n * Rest method for retrieving accounts.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function accounts(): mixed\n {\n $user = $this->getUserFromRequest($this->request);\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'accountId' => new CrmReference($crmProvider),\n ]);\n\n $this->response->getManager()->setSerializer(new JsonSerializer());\n\n if ($this->request->has('accountId')) {\n $accountId = $this->request->input('accountId');\n\n try {\n $account = $this->getAccount($accountId);\n\n $response = $this->response->withItem($account, new AccountTransformer());\n } catch (DomainException) {\n $response = $this->response->errorNotFound('Record not found.');\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n } else {\n $response = $this->response->withCollection($user->team->accounts, new AccountTransformer());\n }\n\n return $response;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $accountId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return Account\n */\n private function getAccount(string $accountId): Account\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountId)->first();\n\n if ($account instanceof Account) {\n return $account;\n }\n\n // Account does not exist locally, import it.\n try {\n return $this->getCrmServiceWithActiveUser($user)->syncAccount($accountId);\n } catch (SocialAccountTokenInvalidException $exception) {\n return $this->response->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.'\n );\n }\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $opportunityId\n *\n * @throws DomainException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Opportunity\n */\n private function getOpportunity(string $opportunityId): Opportunity\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if (! $opportunity instanceof Opportunity) {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n // Sanity check.\n if ($user->team_id !== $opportunity->account->team_id) {\n throw new DomainException('Opportunity not found.');\n }\n\n return $opportunity;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $contactId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Contact\n */\n private function getContact(string $contactId): Contact\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n $contact = $crmService->syncContact($contactId);\n }\n\n return $contact;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $leadId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Lead\n */\n private function getLead(string $leadId): Lead\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $lead = $team->crm->leads()->where('crm_provider_id', $leadId)->first();\n\n if ($lead instanceof Lead) {\n return $lead;\n }\n\n // Lead does not exist locally, import it.\n return $this->getCrmServiceWithActiveUser($user)->syncLead($leadId);\n }\n\n /**\n * Rest method for retrieving contacts.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function contacts(): mixed\n {\n $user = $this->request->user();\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],\n 'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n try {\n // Determine if they wish to retrieve a single contact or multiple for an account.\n if ($this->request->has('contactId')) {\n $contactId = $this->request->input('contactId');\n $contact = $this->getContact($contactId);\n\n $response = $this->response->withItem($contact, new ContactTransformer());\n } else {\n $accountId = $this->request->input('accountId');\n $account = $this->getAccount($accountId);\n\n $response = $this->response->withCollection($account->contacts, new ContactTransformer());\n }\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n\n return $response;\n }\n\n /**\n * Rest method for retrieving leads.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function leads(): mixed\n {\n $user = $this->request->user();\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'leadId' => new CrmReference($crmProvider),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer())\n ->parseIncludes(['stage', 'recordType']);\n\n if ($this->request->has('leadId')) {\n $leadId = $this->request->input('leadId');\n\n try {\n $lead = $this->getLead($leadId);\n\n $response = $this->response->withItem($lead, new LeadTransformer());\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n } else {\n $response = $this->response->withCollection($user->team->leads, new LeadTransformer());\n }\n\n return $response;\n }\n\n /**\n * @param Request $request\n *\n * @throws ValidationException\n *\n * @return JsonResponse\n */\n public function layouts(Request $request): JsonResponse\n {\n $request->validate([\n 'type' => 'required|in:' . implode(',', Layout::$enumTypes),\n ]);\n\n $user = $request->user();\n $type = $request->input('type');\n\n // Take the activity type from the Playbook (default to first for orphaned users).\n if ($user->group_id) {\n $playbook = $user->group->playbook;\n } else {\n /** @var Playbook $playbook */\n $playbook = $user->team->playbooks()->first();\n }\n\n if ($playbook === null) {\n return $this->response->errorUnprocessable('Please configure a Playbook first.');\n }\n\n $layoutTypeParts = explode('-', $type);\n\n $layoutType = sprintf(\n '%s-%s',\n reset($layoutTypeParts),\n end($layoutTypeParts)\n );\n\n /** @var Layout|null $layout */\n $layout = $playbook->layouts()\n ->where('name', ucfirst($playbook->activity_type) . ' Based Layout')\n ->where('type', $layoutType)\n ->first();\n\n if ($layout === null) {\n return $this->response->errorNotFound('Layout not found.');\n }\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer())\n ->parseIncludes([\n 'entities.children.field.options',\n ]);\n\n $transformer = new LayoutTransformer($user->crmProfile)\n ->setNoDefaultActivityTypeFollowUp(true)\n ;\n\n return $this->response->withItem($layout, $transformer);\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmServiceWithActiveUser(User $user): ServiceInterface\n {\n if ($this->crmService === null) {\n $team = $user->getTeam();\n\n if (! $user->isCrmRequired()) {\n $integrationAdmin = $team->getOwner();\n } else {\n $integrationAdmin = $user;\n }\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $integrationAdmin,\n 'providerSlug' => $team->getCrmConfiguration()->getProviderName(),\n ]);\n\n $this->crmService = $crmResolver->prepareCrmService();\n }\n\n return $this->crmService;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse DomainException;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\SalesforceInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\ServiceUnavailableException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\AccountTransformer;\nuse Jiminny\\Http\\Transformers\\ContactTransformer;\nuse Jiminny\\Http\\Transformers\\LayoutTransformer;\nuse Jiminny\\Http\\Transformers\\LeadTransformer;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass CrmController extends Controller\n{\n private const string MESSAGE_GENERAL_EXCEPTION_SEARCHING = 'Sorry, an internal error occurred whilst searching.';\n private const string MESSAGE_GENERAL_EXCEPTION = 'Sorry, an internal error occurred.';\n private ?ServiceInterface $crmService = null;\n\n public function __construct(Response $response)\n {\n parent::__construct($response);\n }\n\n /**\n * Method for searching for remote records by name.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function search(Request $request): mixed\n {\n $allowedScopes = [\n 'lead',\n 'account',\n 'contact',\n 'account-business',\n 'account-person',\n 'contact-business',\n 'contact-person',\n ];\n\n $request->validate([\n 'scopes' => 'required|in:' . implode(',', $allowedScopes) . '|array',\n 'name' => 'required|string|max:100|min:2',\n 'limit' => 'min:1|max:20',\n 'offset' => 'min:0',\n ]);\n\n $scopes = $request->input('scopes');\n $name = $request->input('name');\n $limit = $request->input('limit', 20);\n $offset = $request->input('offset', 0);\n $user = $this->getUserFromRequest($request);\n\n try {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n $crmService->setPage($limit, $offset);\n\n $response = $crmService->find($name, $scopes);\n } catch (SocialAccountTokenInvalidException $exception) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (CrmException $exception) {\n $response = [];\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return $response;\n }\n\n /**\n * Method for retrieving remote opportunities by account or contact.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function opportunities(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n\n try {\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],\n 'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],\n ]);\n\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($this->request->has('contactId')) {\n $contactId = $this->request->input('contactId');\n\n $contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();\n\n // Contact does not exist locally, import it.\n if ($contact === null) {\n $contact = $crmService->syncContact($contactId);\n }\n\n $accountId = $contact->account_id ? $contact->account->crm_provider_id : null;\n } else {\n $contactId = null;\n $accountId = $this->request->input('accountId');\n }\n\n $response = $crmService->findOpportunities($accountId, $contactId, $user->getId());\n } catch (\\InvalidArgumentException $exception) {\n $response = $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException $exception) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return $response;\n }\n\n /**\n * Method for retrieving remote tasks by user.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function activities(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'objectType' => 'in:lead,contact,account',\n 'prospectId' => new CrmReference($crmProvider),\n 'opportunityId' => new CrmReference($crmProvider),\n ]);\n\n try {\n $opportunityId = $request->input('opportunityId');\n $objectType = $request->input('objectType');\n $objectId = $request->input('prospectId');\n\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($objectType === null\n && $crmService instanceof SupportsObjectTypeParseInterface\n ) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n\n // Take the activity type from the Playbook (default to first for orphaned users).\n if ($user->group_id) {\n $playbook = $user->group->playbook;\n } else {\n $playbook = $user->team->playbooks()->first();\n\n // fix empty playbook\n if ($playbook === null) {\n throw new \\InvalidArgumentException('Please configure a Playbook first.');\n }\n }\n\n if ($crmService instanceof SalesforceInterface) {\n /**\n * Salesforce support Tasks and Events,\n * other crms support only Tasks\n */\n $activities = $playbook->activity_type === Playbook::ACTIVITY_TYPE_TASK\n ? $crmService->getTasks($objectType, $objectId, $opportunityId)\n : $crmService->getEvents($objectType, $objectId, $opportunityId);\n } else {\n $activities = $crmService->getTasks($objectType, $objectId, $opportunityId);\n }\n } catch (\\InvalidArgumentException $exception) {\n return $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException $exception) {\n return $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n return $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n\n return $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return [\n 'activities' => $activities,\n 'playbookActivityType' => $playbook->activity_type,\n ];\n }\n\n /**\n * Method for retrieving remote customer details.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function customers(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'objectType' => 'in:lead,contact,account,opportunity,undefined',\n 'providerId' => new CrmReference($crmProvider),\n 'phoneNumber' => 'phone:INTERNATIONAL,US,' . $user->country_code,\n ]);\n\n $objectType = $request->input('objectType');\n $objectId = $request->input('providerId');\n $phoneNumber = $request->input('phoneNumber');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n try {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($objectId) {\n if (($objectType === null || $objectType === 'undefined')\n && $crmService instanceof SupportsObjectTypeParseInterface\n ) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n\n switch ($objectType) {\n case 'lead':\n $lead = $this->getLead($objectId);\n $response = $this->response->withItem($lead, new LeadTransformer());\n\n break;\n\n case 'account':\n $account = $this->getAccount($objectId);\n $response = $this->response->withItem($account, new AccountTransformer());\n\n break;\n\n case 'contact':\n $contact = $this->getContact($objectId);\n $response = $this->response->withItem($contact, new ContactTransformer());\n\n break;\n\n case 'opportunity':\n $opportunity = $this->getOpportunity($objectId);\n $response = $this->response->withItem($opportunity->account, new AccountTransformer());\n\n break;\n\n default:\n $response = $this->response->errorWrongArgs('Sorry, we don\\'t support messaging this type of record.');\n\n break;\n }\n } elseif ($phoneNumber) {\n [$lead, $account, , $contact] = $crmService->matchByPhone(\n $phoneNumber,\n null,\n $user->getId()\n );\n\n if ($lead) {\n $response = $this->response->withItem($lead, new LeadTransformer());\n } elseif ($account) {\n $response = $this->response->withItem($account, new AccountTransformer());\n } elseif ($contact) {\n $response = $this->response->withItem($contact, new ContactTransformer());\n } else {\n $response = $this->response->errorNotFound('Customer not found.');\n }\n } else {\n $response = $this->response->errorWrongArgs('No search data provided.');\n }\n } catch (\\InvalidArgumentException $exception) {\n $response = $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION);\n }\n\n return $response;\n }\n\n /**\n * Rest method for retrieving accounts.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function accounts(): mixed\n {\n $user = $this->getUserFromRequest($this->request);\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'accountId' => new CrmReference($crmProvider),\n ]);\n\n $this->response->getManager()->setSerializer(new JsonSerializer());\n\n if ($this->request->has('accountId')) {\n $accountId = $this->request->input('accountId');\n\n try {\n $account = $this->getAccount($accountId);\n\n $response = $this->response->withItem($account, new AccountTransformer());\n } catch (DomainException) {\n $response = $this->response->errorNotFound('Record not found.');\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n } else {\n $response = $this->response->withCollection($user->team->accounts, new AccountTransformer());\n }\n\n return $response;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $accountId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return Account\n */\n private function getAccount(string $accountId): Account\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountId)->first();\n\n if ($account instanceof Account) {\n return $account;\n }\n\n // Account does not exist locally, import it.\n try {\n return $this->getCrmServiceWithActiveUser($user)->syncAccount($accountId);\n } catch (SocialAccountTokenInvalidException $exception) {\n return $this->response->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.'\n );\n }\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $opportunityId\n *\n * @throws DomainException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Opportunity\n */\n private function getOpportunity(string $opportunityId): Opportunity\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if (! $opportunity instanceof Opportunity) {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n // Sanity check.\n if ($user->team_id !== $opportunity->account->team_id) {\n throw new DomainException('Opportunity not found.');\n }\n\n return $opportunity;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $contactId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Contact\n */\n private function getContact(string $contactId): Contact\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n $contact = $crmService->syncContact($contactId);\n }\n\n return $contact;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $leadId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Lead\n */\n private function getLead(string $leadId): Lead\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $lead = $team->crm->leads()->where('crm_provider_id', $leadId)->first();\n\n if ($lead instanceof Lead) {\n return $lead;\n }\n\n // Lead does not exist locally, import it.\n return $this->getCrmServiceWithActiveUser($user)->syncLead($leadId);\n }\n\n /**\n * Rest method for retrieving contacts.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function contacts(): mixed\n {\n $user = $this->request->user();\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],\n 'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n try {\n // Determine if they wish to retrieve a single contact or multiple for an account.\n if ($this->request->has('contactId')) {\n $contactId = $this->request->input('contactId');\n $contact = $this->getContact($contactId);\n\n $response = $this->response->withItem($contact, new ContactTransformer());\n } else {\n $accountId = $this->request->input('accountId');\n $account = $this->getAccount($accountId);\n\n $response = $this->response->withCollection($account->contacts, new ContactTransformer());\n }\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n\n return $response;\n }\n\n /**\n * Rest method for retrieving leads.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function leads(): mixed\n {\n $user = $this->request->user();\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'leadId' => new CrmReference($crmProvider),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer())\n ->parseIncludes(['stage', 'recordType']);\n\n if ($this->request->has('leadId')) {\n $leadId = $this->request->input('leadId');\n\n try {\n $lead = $this->getLead($leadId);\n\n $response = $this->response->withItem($lead, new LeadTransformer());\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n } else {\n $response = $this->response->withCollection($user->team->leads, new LeadTransformer());\n }\n\n return $response;\n }\n\n /**\n * @param Request $request\n *\n * @throws ValidationException\n *\n * @return JsonResponse\n */\n public function layouts(Request $request): JsonResponse\n {\n $request->validate([\n 'type' => 'required|in:' . implode(',', Layout::$enumTypes),\n ]);\n\n $user = $request->user();\n $type = $request->input('type');\n\n // Take the activity type from the Playbook (default to first for orphaned users).\n if ($user->group_id) {\n $playbook = $user->group->playbook;\n } else {\n /** @var Playbook $playbook */\n $playbook = $user->team->playbooks()->first();\n }\n\n if ($playbook === null) {\n return $this->response->errorUnprocessable('Please configure a Playbook first.');\n }\n\n $layoutTypeParts = explode('-', $type);\n\n $layoutType = sprintf(\n '%s-%s',\n reset($layoutTypeParts),\n end($layoutTypeParts)\n );\n\n /** @var Layout|null $layout */\n $layout = $playbook->layouts()\n ->where('name', ucfirst($playbook->activity_type) . ' Based Layout')\n ->where('type', $layoutType)\n ->first();\n\n if ($layout === null) {\n return $this->response->errorNotFound('Layout not found.');\n }\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer())\n ->parseIncludes([\n 'entities.children.field.options',\n ]);\n\n $transformer = new LayoutTransformer($user->crmProfile)\n ->setNoDefaultActivityTypeFollowUp(true)\n ;\n\n return $this->response->withItem($layout, $transformer);\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmServiceWithActiveUser(User $user): ServiceInterface\n {\n if ($this->crmService === null) {\n $team = $user->getTeam();\n\n if (! $user->isCrmRequired()) {\n $integrationAdmin = $team->getOwner();\n } else {\n $integrationAdmin = $user;\n }\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $integrationAdmin,\n 'providerSlug' => $team->getCrmConfiguration()->getProviderName(),\n ]);\n\n $this->crmService = $crmResolver->prepareCrmService();\n }\n\n return $this->crmService;\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"21","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"18","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"6","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\n\nselect sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id\nwhere u.team_id = 1;\nSELECT * FROM social_accounts WHERE sociable_id = 1635;\nSELECT * FROM users WHERE id = 1635;\n\nselect * from teams where id = 1;\nselect * from users where team_id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role;\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\nSELECT * FROM automated_reports where id = 71;\nSELECT * FROM automated_report_results where report_id = 71;\nUPDATE automated_reports set playbook_categories = NULL where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT `automated_report_results`.* FROM `automated_report_results`\nINNER JOIN `automated_reports`\n ON `automated_report_results`.`report_id` = `automated_reports`.`id`\nWHERE 1=1\n AND `automated_report_results`.`generated_at` IS NOT NULL\n# AND `automated_report_results`.`sent_at` IS NOT NULL\n AND `automated_reports`.`team_id` = 1\n AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$.\"users\"')\n;\n\nSELECT * FROM automated_reports where id = 67;\nSELECT * FROM automated_reports where id = 42;\nSELECT * FROM users WHERE id = 143; # group 28\n\nselect * from teams where id = 3143;\nselect * from crm_configurations where id = 500;\nselect * from users where name = 'Integration Account'; # 1695\nSELECT * FROM social_accounts WHERE sociable_id = 1695;\n\nselect * from activities where crm_configuration_id = 39\nand recording_state = 'recorded' and duration > 60\nand status = 'completed' and actual_start_time >= '2025-12-01';\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;\n\nselect * from leads;\n\nSELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003\nSELECT * FROM activities WHERE id IN (16,422003);\nSELECT * FROM activities where status = 'failed';\n\nSELECT * FROM tracks WHERE activity_id = 422003;\n\nSELECT\n a.*\nFROM activities a\nJOIN users u ON a.user_id = u.id\nWHERE\n a.status = 'completed'\n AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid\n AND a.deleted_at IS NULL\n AND EXISTS (\n SELECT 1 FROM tracks t\n WHERE t.activity_id = a.id\n AND t.type IN ('audio', 'video')\n )\nORDER BY a.actual_start_time DESC\nLIMIT 25;\n\nselect * from teams where id = 19;\nselect * from crm_configurations where provider = 'pipedrive';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 19 and sa.provider = 'pipedrive';\n\nSELECT * FROM social_accounts WHERE id = 1116;\n\nUPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',\nprovider_refresh_token = '5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc',\nexpires = 1779091997,\nstate = 'connected'\nWHERE id = 1116;\n\n \"provider_user_token\": \"v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA\",\n \"provider_refresh_token\": \"5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc\",\n \"expires\": 1779091997,\n\nselect * from crm_field_values;\n\nselect * from crm_fields where type = 'multi-picklist';\nSELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\nSELECT * FROM crm_fields WHERE id = 3014; # 1885\nSELECT * FROM crm_field_values WHERE crm_field_id = 3014;","depth":4,"on_screen":true,"value":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\n\nselect sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id\nwhere u.team_id = 1;\nSELECT * FROM social_accounts WHERE sociable_id = 1635;\nSELECT * FROM users WHERE id = 1635;\n\nselect * from teams where id = 1;\nselect * from users where team_id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role;\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\nSELECT * FROM automated_reports where id = 71;\nSELECT * FROM automated_report_results where report_id = 71;\nUPDATE automated_reports set playbook_categories = NULL where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT `automated_report_results`.* FROM `automated_report_results`\nINNER JOIN `automated_reports`\n ON `automated_report_results`.`report_id` = `automated_reports`.`id`\nWHERE 1=1\n AND `automated_report_results`.`generated_at` IS NOT NULL\n# AND `automated_report_results`.`sent_at` IS NOT NULL\n AND `automated_reports`.`team_id` = 1\n AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$.\"users\"')\n;\n\nSELECT * FROM automated_reports where id = 67;\nSELECT * FROM automated_reports where id = 42;\nSELECT * FROM users WHERE id = 143; # group 28\n\nselect * from teams where id = 3143;\nselect * from crm_configurations where id = 500;\nselect * from users where name = 'Integration Account'; # 1695\nSELECT * FROM social_accounts WHERE sociable_id = 1695;\n\nselect * from activities where crm_configuration_id = 39\nand recording_state = 'recorded' and duration > 60\nand status = 'completed' and actual_start_time >= '2025-12-01';\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;\n\nselect * from leads;\n\nSELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003\nSELECT * FROM activities WHERE id IN (16,422003);\nSELECT * FROM activities where status = 'failed';\n\nSELECT * FROM tracks WHERE activity_id = 422003;\n\nSELECT\n a.*\nFROM activities a\nJOIN users u ON a.user_id = u.id\nWHERE\n a.status = 'completed'\n AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid\n AND a.deleted_at IS NULL\n AND EXISTS (\n SELECT 1 FROM tracks t\n WHERE t.activity_id = a.id\n AND t.type IN ('audio', 'video')\n )\nORDER BY a.actual_start_time DESC\nLIMIT 25;\n\nselect * from teams where id = 19;\nselect * from crm_configurations where provider = 'pipedrive';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 19 and sa.provider = 'pipedrive';\n\nSELECT * FROM social_accounts WHERE id = 1116;\n\nUPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',\nprovider_refresh_token = '5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc',\nexpires = 1779091997,\nstate = 'connected'\nWHERE id = 1116;\n\n \"provider_user_token\": \"v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA\",\n \"provider_refresh_token\": \"5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc\",\n \"expires\": 1779091997,\n\nselect * from crm_field_values;\n\nselect * from crm_fields where type = 'multi-picklist';\nSELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\nSELECT * FROM crm_fields WHERE id = 3014; # 1885\nSELECT * FROM crm_field_values WHERE crm_field_id = 3014;","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}]...
|
6143293950182088657
|
-2607692967562570153
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
48
9
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use DomainException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Jiminny\Contracts\Services\Crm\Provider\SalesforceInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\ServiceUnavailableException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\AccountTransformer;
use Jiminny\Http\Transformers\ContactTransformer;
use Jiminny\Http\Transformers\LayoutTransformer;
use Jiminny\Http\Transformers\LeadTransformer;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Models\Account;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Playbook;
use Jiminny\Models\User;
use Jiminny\Rules\CrmReference;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class CrmController extends Controller
{
private const string MESSAGE_GENERAL_EXCEPTION_SEARCHING = 'Sorry, an internal error occurred whilst searching.';
private const string MESSAGE_GENERAL_EXCEPTION = 'Sorry, an internal error occurred.';
private ?ServiceInterface $crmService = null;
public function __construct(Response $response)
{
parent::__construct($response);
}
/**
* Method for searching for remote records by name.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function search(Request $request): mixed
{
$allowedScopes = [
'lead',
'account',
'contact',
'account-business',
'account-person',
'contact-business',
'contact-person',
];
$request->validate([
'scopes' => 'required|in:' . implode(',', $allowedScopes) . '|array',
'name' => 'required|string|max:100|min:2',
'limit' => 'min:1|max:20',
'offset' => 'min:0',
]);
$scopes = $request->input('scopes');
$name = $request->input('name');
$limit = $request->input('limit', 20);
$offset = $request->input('offset', 0);
$user = $this->getUserFromRequest($request);
try {
$crmService = $this->getCrmServiceWithActiveUser($user);
$crmService->setPage($limit, $offset);
$response = $crmService->find($name, $scopes);
} catch (SocialAccountTokenInvalidException $exception) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (CrmException $exception) {
$response = [];
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return $response;
}
/**
* Method for retrieving remote opportunities by account or contact.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function opportunities(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
try {
$crmProvider = $team->crm->provider;
$request->validate([
'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],
'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],
]);
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($this->request->has('contactId')) {
$contactId = $this->request->input('contactId');
$contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();
// Contact does not exist locally, import it.
if ($contact === null) {
$contact = $crmService->syncContact($contactId);
}
$accountId = $contact->account_id ? $contact->account->crm_provider_id : null;
} else {
$contactId = null;
$accountId = $this->request->input('accountId');
}
$response = $crmService->findOpportunities($accountId, $contactId, $user->getId());
} catch (\InvalidArgumentException $exception) {
$response = $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException $exception) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return $response;
}
/**
* Method for retrieving remote tasks by user.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function activities(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
$crmProvider = $team->crm->provider;
$request->validate([
'objectType' => 'in:lead,contact,account',
'prospectId' => new CrmReference($crmProvider),
'opportunityId' => new CrmReference($crmProvider),
]);
try {
$opportunityId = $request->input('opportunityId');
$objectType = $request->input('objectType');
$objectId = $request->input('prospectId');
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($objectType === null
&& $crmService instanceof SupportsObjectTypeParseInterface
) {
$objectType = $crmService->parseObjectType($objectId);
}
// Take the activity type from the Playbook (default to first for orphaned users).
if ($user->group_id) {
$playbook = $user->group->playbook;
} else {
$playbook = $user->team->playbooks()->first();
// fix empty playbook
if ($playbook === null) {
throw new \InvalidArgumentException('Please configure a Playbook first.');
}
}
if ($crmService instanceof SalesforceInterface) {
/**
* Salesforce support Tasks and Events,
* other crms support only Tasks
*/
$activities = $playbook->activity_type === Playbook::ACTIVITY_TYPE_TASK
? $crmService->getTasks($objectType, $objectId, $opportunityId)
: $crmService->getEvents($objectType, $objectId, $opportunityId);
} else {
$activities = $crmService->getTasks($objectType, $objectId, $opportunityId);
}
} catch (\InvalidArgumentException $exception) {
return $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException $exception) {
return $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
return $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
return $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return [
'activities' => $activities,
'playbookActivityType' => $playbook->activity_type,
];
}
/**
* Method for retrieving remote customer details.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function customers(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
$crmProvider = $team->crm->provider;
$request->validate([
'objectType' => 'in:lead,contact,account,opportunity,undefined',
'providerId' => new CrmReference($crmProvider),
'phoneNumber' => 'phone:INTERNATIONAL,US,' . $user->country_code,
]);
$objectType = $request->input('objectType');
$objectId = $request->input('providerId');
$phoneNumber = $request->input('phoneNumber');
$this->response
->getManager()
->setSerializer(new JsonSerializer());
try {
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($objectId) {
if (($objectType === null || $objectType === 'undefined')
&& $crmService instanceof SupportsObjectTypeParseInterface
) {
$objectType = $crmService->parseObjectType($objectId);
}
switch ($objectType) {
case 'lead':
$lead = $this->getLead($objectId);
$response = $this->response->withItem($lead, new LeadTransformer());
break;
case 'account':
$account = $this->getAccount($objectId);
$response = $this->response->withItem($account, new AccountTransformer());
break;
case 'contact':
$contact = $this->getContact($objectId);
$response = $this->response->withItem($contact, new ContactTransformer());
break;
case 'opportunity':
$opportunity = $this->getOpportunity($objectId);
$response = $this->response->withItem($opportunity->account, new AccountTransformer());
break;
default:
$response = $this->response->errorWrongArgs('Sorry, we don\'t support messaging this type of record.');
break;
}
} elseif ($phoneNumber) {
[$lead, $account, , $contact] = $crmService->matchByPhone(
$phoneNumber,
null,
$user->getId()
);
if ($lead) {
$response = $this->response->withItem($lead, new LeadTransformer());
} elseif ($account) {
$response = $this->response->withItem($account, new AccountTransformer());
} elseif ($contact) {
$response = $this->response->withItem($contact, new ContactTransformer());
} else {
$response = $this->response->errorNotFound('Customer not found.');
}
} else {
$response = $this->response->errorWrongArgs('No search data provided.');
}
} catch (\InvalidArgumentException $exception) {
$response = $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION);
}
return $response;
}
/**
* Rest method for retrieving accounts.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function accounts(): mixed
{
$user = $this->getUserFromRequest($this->request);
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'accountId' => new CrmReference($crmProvider),
]);
$this->response->getManager()->setSerializer(new JsonSerializer());
if ($this->request->has('accountId')) {
$accountId = $this->request->input('accountId');
try {
$account = $this->getAccount($accountId);
$response = $this->response->withItem($account, new AccountTransformer());
} catch (DomainException) {
$response = $this->response->errorNotFound('Record not found.');
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
} else {
$response = $this->response->withCollection($user->team->accounts, new AccountTransformer());
}
return $response;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $accountId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return Account
*/
private function getAccount(string $accountId): Account
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$account = $team->crm->accounts()->where('crm_provider_id', $accountId)->first();
if ($account instanceof Account) {
return $account;
}
// Account does not exist locally, import it.
try {
return $this->getCrmServiceWithActiveUser($user)->syncAccount($accountId);
} catch (SocialAccountTokenInvalidException $exception) {
return $this->response->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.'
);
}
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $opportunityId
*
* @throws DomainException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Opportunity
*/
private function getOpportunity(string $opportunityId): Opportunity
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if (! $opportunity instanceof Opportunity) {
$crmService = $this->getCrmServiceWithActiveUser($user);
$opportunity = $crmService->syncOpportunity($opportunityId);
}
// Sanity check.
if ($user->team_id !== $opportunity->account->team_id) {
throw new DomainException('Opportunity not found.');
}
return $opportunity;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $contactId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Contact
*/
private function getContact(string $contactId): Contact
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$crmService = $this->getCrmServiceWithActiveUser($user);
$contact = $crmService->syncContact($contactId);
}
return $contact;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $leadId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Lead
*/
private function getLead(string $leadId): Lead
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$lead = $team->crm->leads()->where('crm_provider_id', $leadId)->first();
if ($lead instanceof Lead) {
return $lead;
}
// Lead does not exist locally, import it.
return $this->getCrmServiceWithActiveUser($user)->syncLead($leadId);
}
/**
* Rest method for retrieving contacts.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function contacts(): mixed
{
$user = $this->request->user();
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],
'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],
]);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
try {
// Determine if they wish to retrieve a single contact or multiple for an account.
if ($this->request->has('contactId')) {
$contactId = $this->request->input('contactId');
$contact = $this->getContact($contactId);
$response = $this->response->withItem($contact, new ContactTransformer());
} else {
$accountId = $this->request->input('accountId');
$account = $this->getAccount($accountId);
$response = $this->response->withCollection($account->contacts, new ContactTransformer());
}
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
return $response;
}
/**
* Rest method for retrieving leads.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function leads(): mixed
{
$user = $this->request->user();
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'leadId' => new CrmReference($crmProvider),
]);
$this->response
->getManager()
->setSerializer(new JsonSerializer())
->parseIncludes(['stage', 'recordType']);
if ($this->request->has('leadId')) {
$leadId = $this->request->input('leadId');
try {
$lead = $this->getLead($leadId);
$response = $this->response->withItem($lead, new LeadTransformer());
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
} else {
$response = $this->response->withCollection($user->team->leads, new LeadTransformer());
}
return $response;
}
/**
* @param Request $request
*
* @throws ValidationException
*
* @return JsonResponse
*/
public function layouts(Request $request): JsonResponse
{
$request->validate([
'type' => 'required|in:' . implode(',', Layout::$enumTypes),
]);
$user = $request->user();
$type = $request->input('type');
// Take the activity type from the Playbook (default to first for orphaned users).
if ($user->group_id) {
$playbook = $user->group->playbook;
} else {
/** @var Playbook $playbook */
$playbook = $user->team->playbooks()->first();
}
if ($playbook === null) {
return $this->response->errorUnprocessable('Please configure a Playbook first.');
}
$layoutTypeParts = explode('-', $type);
$layoutType = sprintf(
'%s-%s',
reset($layoutTypeParts),
end($layoutTypeParts)
);
/** @var Layout|null $layout */
$layout = $playbook->layouts()
->where('name', ucfirst($playbook->activity_type) . ' Based Layout')
->where('type', $layoutType)
->first();
if ($layout === null) {
return $this->response->errorNotFound('Layout not found.');
}
$this->response
->getManager()
->setSerializer(new JsonSerializer())
->parseIncludes([
'entities.children.field.options',
]);
$transformer = new LayoutTransformer($user->crmProfile)
->setNoDefaultActivityTypeFollowUp(true)
;
return $this->response->withItem($layout, $transformer);
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmServiceWithActiveUser(User $user): ServiceInterface
{
if ($this->crmService === null) {
$team = $user->getTeam();
if (! $user->isCrmRequired()) {
$integrationAdmin = $team->getOwner();
} else {
$integrationAdmin = $user;
}
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $integrationAdmin,
'providerSlug' => $team->getCrmConfiguration()->getProviderName(),
]);
$this->crmService = $crmResolver->prepareCrmService();
}
return $this->crmService;
}
}
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
21
1
18
2
6
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id
where u.team_id = 1;
SELECT * FROM social_accounts WHERE sociable_id = 1635;
SELECT * FROM users WHERE id = 1635;
select * from teams where id = 1;
select * from users where team_id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role;
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
SELECT * FROM automated_reports where id = 71;
SELECT * FROM automated_report_results where report_id = 71;
UPDATE automated_reports set playbook_categories = NULL where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT `automated_report_results`.* FROM `automated_report_results`
INNER JOIN `automated_reports`
ON `automated_report_results`.`report_id` = `automated_reports`.`id`
WHERE 1=1
AND `automated_report_results`.`generated_at` IS NOT NULL
# AND `automated_report_results`.`sent_at` IS NOT NULL
AND `automated_reports`.`team_id` = 1
AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$."users"')
;
SELECT * FROM automated_reports where id = 67;
SELECT * FROM automated_reports where id = 42;
SELECT * FROM users WHERE id = 143; # group 28
select * from teams where id = 3143;
select * from crm_configurations where id = 500;
select * from users where name = 'Integration Account'; # 1695
SELECT * FROM social_accounts WHERE sociable_id = 1695;
select * from activities where crm_configuration_id = 39
and recording_state = 'recorded' and duration > 60
and status = 'completed' and actual_start_time >= '2025-12-01';
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;
select * from leads;
SELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003
SELECT * FROM activities WHERE id IN (16,422003);
SELECT * FROM activities where status = 'failed';
SELECT * FROM tracks WHERE activity_id = 422003;
SELECT
a.*
FROM activities a
JOIN users u ON a.user_id = u.id
WHERE
a.status = 'completed'
AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid
AND a.deleted_at IS NULL
AND EXISTS (
SELECT 1 FROM tracks t
WHERE t.activity_id = a.id
AND t.type IN ('audio', 'video')
)
ORDER BY a.actual_start_time DESC
LIMIT 25;
select * from teams where id = 19;
select * from crm_configurations where provider = 'pipedrive';
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 = 19 and sa.provider = 'pipedrive';
SELECT * FROM social_accounts WHERE id = 1116;
UPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',
provider_refresh_token = '5034113:[TELEGRAM_TOKEN]b2bfc',
expires = 1779091997,
state = 'connected'
WHERE id = 1116;
"provider_user_token": "v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA",
"provider_refresh_token": "5034113:[TELEGRAM_TOKEN]b2bfc",
"expires": 1779091997,
select * from crm_field_values;
select * from crm_fields where type = 'multi-picklist';
SELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
SELECT * FROM crm_fields WHERE id = 3014; # 1885
SELECT * FROM crm_field_values WHERE crm_field_id = 3014;
Project
Project...
|
79490
|
NULL
|
NULL
|
NULL
|
|
79501
|
2787
|
59
|
2026-05-28T06:32:07.149473+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949927149_m2.jpg...
|
PhpStorm
|
faVsco.js – CrmController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
48
9
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use DomainException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Jiminny\Contracts\Services\Crm\Provider\SalesforceInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\ServiceUnavailableException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\AccountTransformer;
use Jiminny\Http\Transformers\ContactTransformer;
use Jiminny\Http\Transformers\LayoutTransformer;
use Jiminny\Http\Transformers\LeadTransformer;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Models\Account;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Playbook;
use Jiminny\Models\User;
use Jiminny\Rules\CrmReference;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class CrmController extends Controller
{
private const string MESSAGE_GENERAL_EXCEPTION_SEARCHING = 'Sorry, an internal error occurred whilst searching.';
private const string MESSAGE_GENERAL_EXCEPTION = 'Sorry, an internal error occurred.';
private ?ServiceInterface $crmService = null;
public function __construct(Response $response)
{
parent::__construct($response);
}
/**
* Method for searching for remote records by name.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function search(Request $request): mixed
{
$allowedScopes = [
'lead',
'account',
'contact',
'account-business',
'account-person',
'contact-business',
'contact-person',
];
$request->validate([
'scopes' => 'required|in:' . implode(',', $allowedScopes) . '|array',
'name' => 'required|string|max:100|min:2',
'limit' => 'min:1|max:20',
'offset' => 'min:0',
]);
$scopes = $request->input('scopes');
$name = $request->input('name');
$limit = $request->input('limit', 20);
$offset = $request->input('offset', 0);
$user = $this->getUserFromRequest($request);
try {
$crmService = $this->getCrmServiceWithActiveUser($user);
$crmService->setPage($limit, $offset);
$response = $crmService->find($name, $scopes);
} catch (SocialAccountTokenInvalidException $exception) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (CrmException $exception) {
$response = [];
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return $response;
}
/**
* Method for retrieving remote opportunities by account or contact.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function opportunities(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
try {
$crmProvider = $team->crm->provider;
$request->validate([
'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],
'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],
]);
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($this->request->has('contactId')) {
$contactId = $this->request->input('contactId');
$contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();
// Contact does not exist locally, import it.
if ($contact === null) {
$contact = $crmService->syncContact($contactId);
}
$accountId = $contact->account_id ? $contact->account->crm_provider_id : null;
} else {
$contactId = null;
$accountId = $this->request->input('accountId');
}
$response = $crmService->findOpportunities($accountId, $contactId, $user->getId());
} catch (\InvalidArgumentException $exception) {
$response = $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException $exception) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return $response;
}
/**
* Method for retrieving remote tasks by user.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function activities(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
$crmProvider = $team->crm->provider;
$request->validate([
'objectType' => 'in:lead,contact,account',
'prospectId' => new CrmReference($crmProvider),
'opportunityId' => new CrmReference($crmProvider),
]);
try {
$opportunityId = $request->input('opportunityId');
$objectType = $request->input('objectType');
$objectId = $request->input('prospectId');
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($objectType === null
&& $crmService instanceof SupportsObjectTypeParseInterface
) {
$objectType = $crmService->parseObjectType($objectId);
}
// Take the activity type from the Playbook (default to first for orphaned users).
if ($user->group_id) {
$playbook = $user->group->playbook;
} else {
$playbook = $user->team->playbooks()->first();
// fix empty playbook
if ($playbook === null) {
throw new \InvalidArgumentException('Please configure a Playbook first.');
}
}
if ($crmService instanceof SalesforceInterface) {
/**
* Salesforce support Tasks and Events,
* other crms support only Tasks
*/
$activities = $playbook->activity_type === Playbook::ACTIVITY_TYPE_TASK
? $crmService->getTasks($objectType, $objectId, $opportunityId)
: $crmService->getEvents($objectType, $objectId, $opportunityId);
} else {
$activities = $crmService->getTasks($objectType, $objectId, $opportunityId);
}
} catch (\InvalidArgumentException $exception) {
return $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException $exception) {
return $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
return $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
return $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return [
'activities' => $activities,
'playbookActivityType' => $playbook->activity_type,
];
}
/**
* Method for retrieving remote customer details.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function customers(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
$crmProvider = $team->crm->provider;
$request->validate([
'objectType' => 'in:lead,contact,account,opportunity,undefined',
'providerId' => new CrmReference($crmProvider),
'phoneNumber' => 'phone:INTERNATIONAL,US,' . $user->country_code,
]);
$objectType = $request->input('objectType');
$objectId = $request->input('providerId');
$phoneNumber = $request->input('phoneNumber');
$this->response
->getManager()
->setSerializer(new JsonSerializer());
try {
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($objectId) {
if (($objectType === null || $objectType === 'undefined')
&& $crmService instanceof SupportsObjectTypeParseInterface
) {
$objectType = $crmService->parseObjectType($objectId);
}
switch ($objectType) {
case 'lead':
$lead = $this->getLead($objectId);
$response = $this->response->withItem($lead, new LeadTransformer());
break;
case 'account':
$account = $this->getAccount($objectId);
$response = $this->response->withItem($account, new AccountTransformer());
break;
case 'contact':
$contact = $this->getContact($objectId);
$response = $this->response->withItem($contact, new ContactTransformer());
break;
case 'opportunity':
$opportunity = $this->getOpportunity($objectId);
$response = $this->response->withItem($opportunity->account, new AccountTransformer());
break;
default:
$response = $this->response->errorWrongArgs('Sorry, we don\'t support messaging this type of record.');
break;
}
} elseif ($phoneNumber) {
[$lead, $account, , $contact] = $crmService->matchByPhone(
$phoneNumber,
null,
$user->getId()
);
if ($lead) {
$response = $this->response->withItem($lead, new LeadTransformer());
} elseif ($account) {
$response = $this->response->withItem($account, new AccountTransformer());
} elseif ($contact) {
$response = $this->response->withItem($contact, new ContactTransformer());
} else {
$response = $this->response->errorNotFound('Customer not found.');
}
} else {
$response = $this->response->errorWrongArgs('No search data provided.');
}
} catch (\InvalidArgumentException $exception) {
$response = $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION);
}
return $response;
}
/**
* Rest method for retrieving accounts.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function accounts(): mixed
{
$user = $this->getUserFromRequest($this->request);
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'accountId' => new CrmReference($crmProvider),
]);
$this->response->getManager()->setSerializer(new JsonSerializer());
if ($this->request->has('accountId')) {
$accountId = $this->request->input('accountId');
try {
$account = $this->getAccount($accountId);
$response = $this->response->withItem($account, new AccountTransformer());
} catch (DomainException) {
$response = $this->response->errorNotFound('Record not found.');
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
} else {
$response = $this->response->withCollection($user->team->accounts, new AccountTransformer());
}
return $response;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $accountId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return Account
*/
private function getAccount(string $accountId): Account
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$account = $team->crm->accounts()->where('crm_provider_id', $accountId)->first();
if ($account instanceof Account) {
return $account;
}
// Account does not exist locally, import it.
try {
return $this->getCrmServiceWithActiveUser($user)->syncAccount($accountId);
} catch (SocialAccountTokenInvalidException $exception) {
return $this->response->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.'
);
}
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $opportunityId
*
* @throws DomainException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Opportunity
*/
private function getOpportunity(string $opportunityId): Opportunity
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if (! $opportunity instanceof Opportunity) {
$crmService = $this->getCrmServiceWithActiveUser($user);
$opportunity = $crmService->syncOpportunity($opportunityId);
}
// Sanity check.
if ($user->team_id !== $opportunity->account->team_id) {
throw new DomainException('Opportunity not found.');
}
return $opportunity;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $contactId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Contact
*/
private function getContact(string $contactId): Contact
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$crmService = $this->getCrmServiceWithActiveUser($user);
$contact = $crmService->syncContact($contactId);
}
return $contact;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $leadId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Lead
*/
private function getLead(string $leadId): Lead
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$lead = $team->crm->leads()->where('crm_provider_id', $leadId)->first();
if ($lead instanceof Lead) {
return $lead;
}
// Lead does not exist locally, import it.
return $this->getCrmServiceWithActiveUser($user)->syncLead($leadId);
}
/**
* Rest method for retrieving contacts.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function contacts(): mixed
{
$user = $this->request->user();
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],
'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],
]);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
try {
// Determine if they wish to retrieve a single contact or multiple for an account.
if ($this->request->has('contactId')) {
$contactId = $this->request->input('contactId');
$contact = $this->getContact($contactId);
$response = $this->response->withItem($contact, new ContactTransformer());
} else {
$accountId = $this->request->input('accountId');
$account = $this->getAccount($accountId);
$response = $this->response->withCollection($account->contacts, new ContactTransformer());
}
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
return $response;
}
/**
* Rest method for retrieving leads.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function leads(): mixed
{
$user = $this->request->user();
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'leadId' => new CrmReference($crmProvider),
]);
$this->response
->getManager()
->setSerializer(new JsonSerializer())
->parseIncludes(['stage', 'recordType']);
if ($this->request->has('leadId')) {
$leadId = $this->request->input('leadId');
try {
$lead = $this->getLead($leadId);
$response = $this->response->withItem($lead, new LeadTransformer());
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
} else {
$response = $this->response->withCollection($user->team->leads, new LeadTransformer());
}
return $response;
}
/**
* @param Request $request
*
* @throws ValidationException
*
* @return JsonResponse
*/
public function layouts(Request $request): JsonResponse
{
$request->validate([
'type' => 'required|in:' . implode(',', Layout::$enumTypes),
]);
$user = $request->user();
$type = $request->input('type');
// Take the activity type from the Playbook (default to first for orphaned users).
if ($user->group_id) {
$playbook = $user->group->playbook;
} else {
/** @var Playbook $playbook */
$playbook = $user->team->playbooks()->first();
}
if ($playbook === null) {
return $this->response->errorUnprocessable('Please configure a Playbook first.');
}
$layoutTypeParts = explode('-', $type);
$layoutType = sprintf(
'%s-%s',
reset($layoutTypeParts),
end($layoutTypeParts)
);
/** @var Layout|null $layout */
$layout = $playbook->layouts()
->where('name', ucfirst($playbook->activity_type) . ' Based Layout')
->where('type', $layoutType)
->first();
if ($layout === null) {
return $this->response->errorNotFound('Layout not found.');
}
$this->response
->getManager()
->setSerializer(new JsonSerializer())
->parseIncludes([
'entities.children.field.options',
]);
$transformer = new LayoutTransformer($user->crmProfile)
->setNoDefaultActivityTypeFollowUp(true)
;
return $this->response->withItem($layout, $transformer);
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmServiceWithActiveUser(User $user): ServiceInterface
{
if ($this->crmService === null) {
$team = $user->getTeam();
if (! $user->isCrmRequired()) {
$integrationAdmin = $team->getOwner();
} else {
$integrationAdmin = $user;
}
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $integrationAdmin,
'providerSlug' => $team->getCrmConfiguration()->getProviderName(),
]);
$this->crmService = $crmResolver->prepareCrmService();
}
return $this->crmService;
}
}
Execute...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09740692,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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.8374335,"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":"TextRelayServiceTest","depth":6,"bounds":{"left":0.85272604,"top":0.019952115,"width":0.062832445,"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 'TextRelayServiceTest'","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 'TextRelayServiceTest'","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":"48","depth":4,"bounds":{"left":0.375,"top":0.10055866,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"9","depth":4,"bounds":{"left":0.38730052,"top":0.10055866,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39694148,"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.40425533,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse DomainException;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\SalesforceInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\ServiceUnavailableException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\AccountTransformer;\nuse Jiminny\\Http\\Transformers\\ContactTransformer;\nuse Jiminny\\Http\\Transformers\\LayoutTransformer;\nuse Jiminny\\Http\\Transformers\\LeadTransformer;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass CrmController extends Controller\n{\n private const string MESSAGE_GENERAL_EXCEPTION_SEARCHING = 'Sorry, an internal error occurred whilst searching.';\n private const string MESSAGE_GENERAL_EXCEPTION = 'Sorry, an internal error occurred.';\n private ?ServiceInterface $crmService = null;\n\n public function __construct(Response $response)\n {\n parent::__construct($response);\n }\n\n /**\n * Method for searching for remote records by name.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function search(Request $request): mixed\n {\n $allowedScopes = [\n 'lead',\n 'account',\n 'contact',\n 'account-business',\n 'account-person',\n 'contact-business',\n 'contact-person',\n ];\n\n $request->validate([\n 'scopes' => 'required|in:' . implode(',', $allowedScopes) . '|array',\n 'name' => 'required|string|max:100|min:2',\n 'limit' => 'min:1|max:20',\n 'offset' => 'min:0',\n ]);\n\n $scopes = $request->input('scopes');\n $name = $request->input('name');\n $limit = $request->input('limit', 20);\n $offset = $request->input('offset', 0);\n $user = $this->getUserFromRequest($request);\n\n try {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n $crmService->setPage($limit, $offset);\n\n $response = $crmService->find($name, $scopes);\n } catch (SocialAccountTokenInvalidException $exception) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (CrmException $exception) {\n $response = [];\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return $response;\n }\n\n /**\n * Method for retrieving remote opportunities by account or contact.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function opportunities(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n\n try {\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],\n 'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],\n ]);\n\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($this->request->has('contactId')) {\n $contactId = $this->request->input('contactId');\n\n $contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();\n\n // Contact does not exist locally, import it.\n if ($contact === null) {\n $contact = $crmService->syncContact($contactId);\n }\n\n $accountId = $contact->account_id ? $contact->account->crm_provider_id : null;\n } else {\n $contactId = null;\n $accountId = $this->request->input('accountId');\n }\n\n $response = $crmService->findOpportunities($accountId, $contactId, $user->getId());\n } catch (\\InvalidArgumentException $exception) {\n $response = $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException $exception) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return $response;\n }\n\n /**\n * Method for retrieving remote tasks by user.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function activities(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'objectType' => 'in:lead,contact,account',\n 'prospectId' => new CrmReference($crmProvider),\n 'opportunityId' => new CrmReference($crmProvider),\n ]);\n\n try {\n $opportunityId = $request->input('opportunityId');\n $objectType = $request->input('objectType');\n $objectId = $request->input('prospectId');\n\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($objectType === null\n && $crmService instanceof SupportsObjectTypeParseInterface\n ) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n\n // Take the activity type from the Playbook (default to first for orphaned users).\n if ($user->group_id) {\n $playbook = $user->group->playbook;\n } else {\n $playbook = $user->team->playbooks()->first();\n\n // fix empty playbook\n if ($playbook === null) {\n throw new \\InvalidArgumentException('Please configure a Playbook first.');\n }\n }\n\n if ($crmService instanceof SalesforceInterface) {\n /**\n * Salesforce support Tasks and Events,\n * other crms support only Tasks\n */\n $activities = $playbook->activity_type === Playbook::ACTIVITY_TYPE_TASK\n ? $crmService->getTasks($objectType, $objectId, $opportunityId)\n : $crmService->getEvents($objectType, $objectId, $opportunityId);\n } else {\n $activities = $crmService->getTasks($objectType, $objectId, $opportunityId);\n }\n } catch (\\InvalidArgumentException $exception) {\n return $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException $exception) {\n return $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n return $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n\n return $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return [\n 'activities' => $activities,\n 'playbookActivityType' => $playbook->activity_type,\n ];\n }\n\n /**\n * Method for retrieving remote customer details.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function customers(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'objectType' => 'in:lead,contact,account,opportunity,undefined',\n 'providerId' => new CrmReference($crmProvider),\n 'phoneNumber' => 'phone:INTERNATIONAL,US,' . $user->country_code,\n ]);\n\n $objectType = $request->input('objectType');\n $objectId = $request->input('providerId');\n $phoneNumber = $request->input('phoneNumber');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n try {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($objectId) {\n if (($objectType === null || $objectType === 'undefined')\n && $crmService instanceof SupportsObjectTypeParseInterface\n ) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n\n switch ($objectType) {\n case 'lead':\n $lead = $this->getLead($objectId);\n $response = $this->response->withItem($lead, new LeadTransformer());\n\n break;\n\n case 'account':\n $account = $this->getAccount($objectId);\n $response = $this->response->withItem($account, new AccountTransformer());\n\n break;\n\n case 'contact':\n $contact = $this->getContact($objectId);\n $response = $this->response->withItem($contact, new ContactTransformer());\n\n break;\n\n case 'opportunity':\n $opportunity = $this->getOpportunity($objectId);\n $response = $this->response->withItem($opportunity->account, new AccountTransformer());\n\n break;\n\n default:\n $response = $this->response->errorWrongArgs('Sorry, we don\\'t support messaging this type of record.');\n\n break;\n }\n } elseif ($phoneNumber) {\n [$lead, $account, , $contact] = $crmService->matchByPhone(\n $phoneNumber,\n null,\n $user->getId()\n );\n\n if ($lead) {\n $response = $this->response->withItem($lead, new LeadTransformer());\n } elseif ($account) {\n $response = $this->response->withItem($account, new AccountTransformer());\n } elseif ($contact) {\n $response = $this->response->withItem($contact, new ContactTransformer());\n } else {\n $response = $this->response->errorNotFound('Customer not found.');\n }\n } else {\n $response = $this->response->errorWrongArgs('No search data provided.');\n }\n } catch (\\InvalidArgumentException $exception) {\n $response = $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION);\n }\n\n return $response;\n }\n\n /**\n * Rest method for retrieving accounts.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function accounts(): mixed\n {\n $user = $this->getUserFromRequest($this->request);\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'accountId' => new CrmReference($crmProvider),\n ]);\n\n $this->response->getManager()->setSerializer(new JsonSerializer());\n\n if ($this->request->has('accountId')) {\n $accountId = $this->request->input('accountId');\n\n try {\n $account = $this->getAccount($accountId);\n\n $response = $this->response->withItem($account, new AccountTransformer());\n } catch (DomainException) {\n $response = $this->response->errorNotFound('Record not found.');\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n } else {\n $response = $this->response->withCollection($user->team->accounts, new AccountTransformer());\n }\n\n return $response;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $accountId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return Account\n */\n private function getAccount(string $accountId): Account\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountId)->first();\n\n if ($account instanceof Account) {\n return $account;\n }\n\n // Account does not exist locally, import it.\n try {\n return $this->getCrmServiceWithActiveUser($user)->syncAccount($accountId);\n } catch (SocialAccountTokenInvalidException $exception) {\n return $this->response->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.'\n );\n }\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $opportunityId\n *\n * @throws DomainException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Opportunity\n */\n private function getOpportunity(string $opportunityId): Opportunity\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if (! $opportunity instanceof Opportunity) {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n // Sanity check.\n if ($user->team_id !== $opportunity->account->team_id) {\n throw new DomainException('Opportunity not found.');\n }\n\n return $opportunity;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $contactId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Contact\n */\n private function getContact(string $contactId): Contact\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n $contact = $crmService->syncContact($contactId);\n }\n\n return $contact;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $leadId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Lead\n */\n private function getLead(string $leadId): Lead\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $lead = $team->crm->leads()->where('crm_provider_id', $leadId)->first();\n\n if ($lead instanceof Lead) {\n return $lead;\n }\n\n // Lead does not exist locally, import it.\n return $this->getCrmServiceWithActiveUser($user)->syncLead($leadId);\n }\n\n /**\n * Rest method for retrieving contacts.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function contacts(): mixed\n {\n $user = $this->request->user();\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],\n 'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n try {\n // Determine if they wish to retrieve a single contact or multiple for an account.\n if ($this->request->has('contactId')) {\n $contactId = $this->request->input('contactId');\n $contact = $this->getContact($contactId);\n\n $response = $this->response->withItem($contact, new ContactTransformer());\n } else {\n $accountId = $this->request->input('accountId');\n $account = $this->getAccount($accountId);\n\n $response = $this->response->withCollection($account->contacts, new ContactTransformer());\n }\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n\n return $response;\n }\n\n /**\n * Rest method for retrieving leads.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function leads(): mixed\n {\n $user = $this->request->user();\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'leadId' => new CrmReference($crmProvider),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer())\n ->parseIncludes(['stage', 'recordType']);\n\n if ($this->request->has('leadId')) {\n $leadId = $this->request->input('leadId');\n\n try {\n $lead = $this->getLead($leadId);\n\n $response = $this->response->withItem($lead, new LeadTransformer());\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n } else {\n $response = $this->response->withCollection($user->team->leads, new LeadTransformer());\n }\n\n return $response;\n }\n\n /**\n * @param Request $request\n *\n * @throws ValidationException\n *\n * @return JsonResponse\n */\n public function layouts(Request $request): JsonResponse\n {\n $request->validate([\n 'type' => 'required|in:' . implode(',', Layout::$enumTypes),\n ]);\n\n $user = $request->user();\n $type = $request->input('type');\n\n // Take the activity type from the Playbook (default to first for orphaned users).\n if ($user->group_id) {\n $playbook = $user->group->playbook;\n } else {\n /** @var Playbook $playbook */\n $playbook = $user->team->playbooks()->first();\n }\n\n if ($playbook === null) {\n return $this->response->errorUnprocessable('Please configure a Playbook first.');\n }\n\n $layoutTypeParts = explode('-', $type);\n\n $layoutType = sprintf(\n '%s-%s',\n reset($layoutTypeParts),\n end($layoutTypeParts)\n );\n\n /** @var Layout|null $layout */\n $layout = $playbook->layouts()\n ->where('name', ucfirst($playbook->activity_type) . ' Based Layout')\n ->where('type', $layoutType)\n ->first();\n\n if ($layout === null) {\n return $this->response->errorNotFound('Layout not found.');\n }\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer())\n ->parseIncludes([\n 'entities.children.field.options',\n ]);\n\n $transformer = new LayoutTransformer($user->crmProfile)\n ->setNoDefaultActivityTypeFollowUp(true)\n ;\n\n return $this->response->withItem($layout, $transformer);\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmServiceWithActiveUser(User $user): ServiceInterface\n {\n if ($this->crmService === null) {\n $team = $user->getTeam();\n\n if (! $user->isCrmRequired()) {\n $integrationAdmin = $team->getOwner();\n } else {\n $integrationAdmin = $user;\n }\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $integrationAdmin,\n 'providerSlug' => $team->getCrmConfiguration()->getProviderName(),\n ]);\n\n $this->crmService = $crmResolver->prepareCrmService();\n }\n\n return $this->crmService;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse DomainException;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\SalesforceInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\ServiceUnavailableException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\AccountTransformer;\nuse Jiminny\\Http\\Transformers\\ContactTransformer;\nuse Jiminny\\Http\\Transformers\\LayoutTransformer;\nuse Jiminny\\Http\\Transformers\\LeadTransformer;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass CrmController extends Controller\n{\n private const string MESSAGE_GENERAL_EXCEPTION_SEARCHING = 'Sorry, an internal error occurred whilst searching.';\n private const string MESSAGE_GENERAL_EXCEPTION = 'Sorry, an internal error occurred.';\n private ?ServiceInterface $crmService = null;\n\n public function __construct(Response $response)\n {\n parent::__construct($response);\n }\n\n /**\n * Method for searching for remote records by name.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function search(Request $request): mixed\n {\n $allowedScopes = [\n 'lead',\n 'account',\n 'contact',\n 'account-business',\n 'account-person',\n 'contact-business',\n 'contact-person',\n ];\n\n $request->validate([\n 'scopes' => 'required|in:' . implode(',', $allowedScopes) . '|array',\n 'name' => 'required|string|max:100|min:2',\n 'limit' => 'min:1|max:20',\n 'offset' => 'min:0',\n ]);\n\n $scopes = $request->input('scopes');\n $name = $request->input('name');\n $limit = $request->input('limit', 20);\n $offset = $request->input('offset', 0);\n $user = $this->getUserFromRequest($request);\n\n try {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n $crmService->setPage($limit, $offset);\n\n $response = $crmService->find($name, $scopes);\n } catch (SocialAccountTokenInvalidException $exception) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (CrmException $exception) {\n $response = [];\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return $response;\n }\n\n /**\n * Method for retrieving remote opportunities by account or contact.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function opportunities(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n\n try {\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],\n 'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],\n ]);\n\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($this->request->has('contactId')) {\n $contactId = $this->request->input('contactId');\n\n $contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();\n\n // Contact does not exist locally, import it.\n if ($contact === null) {\n $contact = $crmService->syncContact($contactId);\n }\n\n $accountId = $contact->account_id ? $contact->account->crm_provider_id : null;\n } else {\n $contactId = null;\n $accountId = $this->request->input('accountId');\n }\n\n $response = $crmService->findOpportunities($accountId, $contactId, $user->getId());\n } catch (\\InvalidArgumentException $exception) {\n $response = $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException $exception) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return $response;\n }\n\n /**\n * Method for retrieving remote tasks by user.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function activities(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'objectType' => 'in:lead,contact,account',\n 'prospectId' => new CrmReference($crmProvider),\n 'opportunityId' => new CrmReference($crmProvider),\n ]);\n\n try {\n $opportunityId = $request->input('opportunityId');\n $objectType = $request->input('objectType');\n $objectId = $request->input('prospectId');\n\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($objectType === null\n && $crmService instanceof SupportsObjectTypeParseInterface\n ) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n\n // Take the activity type from the Playbook (default to first for orphaned users).\n if ($user->group_id) {\n $playbook = $user->group->playbook;\n } else {\n $playbook = $user->team->playbooks()->first();\n\n // fix empty playbook\n if ($playbook === null) {\n throw new \\InvalidArgumentException('Please configure a Playbook first.');\n }\n }\n\n if ($crmService instanceof SalesforceInterface) {\n /**\n * Salesforce support Tasks and Events,\n * other crms support only Tasks\n */\n $activities = $playbook->activity_type === Playbook::ACTIVITY_TYPE_TASK\n ? $crmService->getTasks($objectType, $objectId, $opportunityId)\n : $crmService->getEvents($objectType, $objectId, $opportunityId);\n } else {\n $activities = $crmService->getTasks($objectType, $objectId, $opportunityId);\n }\n } catch (\\InvalidArgumentException $exception) {\n return $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException $exception) {\n return $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n return $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n\n return $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return [\n 'activities' => $activities,\n 'playbookActivityType' => $playbook->activity_type,\n ];\n }\n\n /**\n * Method for retrieving remote customer details.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function customers(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'objectType' => 'in:lead,contact,account,opportunity,undefined',\n 'providerId' => new CrmReference($crmProvider),\n 'phoneNumber' => 'phone:INTERNATIONAL,US,' . $user->country_code,\n ]);\n\n $objectType = $request->input('objectType');\n $objectId = $request->input('providerId');\n $phoneNumber = $request->input('phoneNumber');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n try {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($objectId) {\n if (($objectType === null || $objectType === 'undefined')\n && $crmService instanceof SupportsObjectTypeParseInterface\n ) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n\n switch ($objectType) {\n case 'lead':\n $lead = $this->getLead($objectId);\n $response = $this->response->withItem($lead, new LeadTransformer());\n\n break;\n\n case 'account':\n $account = $this->getAccount($objectId);\n $response = $this->response->withItem($account, new AccountTransformer());\n\n break;\n\n case 'contact':\n $contact = $this->getContact($objectId);\n $response = $this->response->withItem($contact, new ContactTransformer());\n\n break;\n\n case 'opportunity':\n $opportunity = $this->getOpportunity($objectId);\n $response = $this->response->withItem($opportunity->account, new AccountTransformer());\n\n break;\n\n default:\n $response = $this->response->errorWrongArgs('Sorry, we don\\'t support messaging this type of record.');\n\n break;\n }\n } elseif ($phoneNumber) {\n [$lead, $account, , $contact] = $crmService->matchByPhone(\n $phoneNumber,\n null,\n $user->getId()\n );\n\n if ($lead) {\n $response = $this->response->withItem($lead, new LeadTransformer());\n } elseif ($account) {\n $response = $this->response->withItem($account, new AccountTransformer());\n } elseif ($contact) {\n $response = $this->response->withItem($contact, new ContactTransformer());\n } else {\n $response = $this->response->errorNotFound('Customer not found.');\n }\n } else {\n $response = $this->response->errorWrongArgs('No search data provided.');\n }\n } catch (\\InvalidArgumentException $exception) {\n $response = $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION);\n }\n\n return $response;\n }\n\n /**\n * Rest method for retrieving accounts.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function accounts(): mixed\n {\n $user = $this->getUserFromRequest($this->request);\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'accountId' => new CrmReference($crmProvider),\n ]);\n\n $this->response->getManager()->setSerializer(new JsonSerializer());\n\n if ($this->request->has('accountId')) {\n $accountId = $this->request->input('accountId');\n\n try {\n $account = $this->getAccount($accountId);\n\n $response = $this->response->withItem($account, new AccountTransformer());\n } catch (DomainException) {\n $response = $this->response->errorNotFound('Record not found.');\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n } else {\n $response = $this->response->withCollection($user->team->accounts, new AccountTransformer());\n }\n\n return $response;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $accountId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return Account\n */\n private function getAccount(string $accountId): Account\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountId)->first();\n\n if ($account instanceof Account) {\n return $account;\n }\n\n // Account does not exist locally, import it.\n try {\n return $this->getCrmServiceWithActiveUser($user)->syncAccount($accountId);\n } catch (SocialAccountTokenInvalidException $exception) {\n return $this->response->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.'\n );\n }\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $opportunityId\n *\n * @throws DomainException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Opportunity\n */\n private function getOpportunity(string $opportunityId): Opportunity\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if (! $opportunity instanceof Opportunity) {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n // Sanity check.\n if ($user->team_id !== $opportunity->account->team_id) {\n throw new DomainException('Opportunity not found.');\n }\n\n return $opportunity;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $contactId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Contact\n */\n private function getContact(string $contactId): Contact\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n $contact = $crmService->syncContact($contactId);\n }\n\n return $contact;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $leadId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Lead\n */\n private function getLead(string $leadId): Lead\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $lead = $team->crm->leads()->where('crm_provider_id', $leadId)->first();\n\n if ($lead instanceof Lead) {\n return $lead;\n }\n\n // Lead does not exist locally, import it.\n return $this->getCrmServiceWithActiveUser($user)->syncLead($leadId);\n }\n\n /**\n * Rest method for retrieving contacts.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function contacts(): mixed\n {\n $user = $this->request->user();\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],\n 'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n try {\n // Determine if they wish to retrieve a single contact or multiple for an account.\n if ($this->request->has('contactId')) {\n $contactId = $this->request->input('contactId');\n $contact = $this->getContact($contactId);\n\n $response = $this->response->withItem($contact, new ContactTransformer());\n } else {\n $accountId = $this->request->input('accountId');\n $account = $this->getAccount($accountId);\n\n $response = $this->response->withCollection($account->contacts, new ContactTransformer());\n }\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n\n return $response;\n }\n\n /**\n * Rest method for retrieving leads.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function leads(): mixed\n {\n $user = $this->request->user();\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'leadId' => new CrmReference($crmProvider),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer())\n ->parseIncludes(['stage', 'recordType']);\n\n if ($this->request->has('leadId')) {\n $leadId = $this->request->input('leadId');\n\n try {\n $lead = $this->getLead($leadId);\n\n $response = $this->response->withItem($lead, new LeadTransformer());\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n } else {\n $response = $this->response->withCollection($user->team->leads, new LeadTransformer());\n }\n\n return $response;\n }\n\n /**\n * @param Request $request\n *\n * @throws ValidationException\n *\n * @return JsonResponse\n */\n public function layouts(Request $request): JsonResponse\n {\n $request->validate([\n 'type' => 'required|in:' . implode(',', Layout::$enumTypes),\n ]);\n\n $user = $request->user();\n $type = $request->input('type');\n\n // Take the activity type from the Playbook (default to first for orphaned users).\n if ($user->group_id) {\n $playbook = $user->group->playbook;\n } else {\n /** @var Playbook $playbook */\n $playbook = $user->team->playbooks()->first();\n }\n\n if ($playbook === null) {\n return $this->response->errorUnprocessable('Please configure a Playbook first.');\n }\n\n $layoutTypeParts = explode('-', $type);\n\n $layoutType = sprintf(\n '%s-%s',\n reset($layoutTypeParts),\n end($layoutTypeParts)\n );\n\n /** @var Layout|null $layout */\n $layout = $playbook->layouts()\n ->where('name', ucfirst($playbook->activity_type) . ' Based Layout')\n ->where('type', $layoutType)\n ->first();\n\n if ($layout === null) {\n return $this->response->errorNotFound('Layout not found.');\n }\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer())\n ->parseIncludes([\n 'entities.children.field.options',\n ]);\n\n $transformer = new LayoutTransformer($user->crmProfile)\n ->setNoDefaultActivityTypeFollowUp(true)\n ;\n\n return $this->response->withItem($layout, $transformer);\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmServiceWithActiveUser(User $user): ServiceInterface\n {\n if ($this->crmService === null) {\n $team = $user->getTeam();\n\n if (! $user->isCrmRequired()) {\n $integrationAdmin = $team->getOwner();\n } else {\n $integrationAdmin = $user;\n }\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $integrationAdmin,\n 'providerSlug' => $team->getCrmConfiguration()->getProviderName(),\n ]);\n\n $this->crmService = $crmResolver->prepareCrmService();\n }\n\n return $this->crmService;\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"bounds":{"left":0.41289893,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-1311957938943984410
|
-3752135871855184809
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
48
9
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use DomainException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Jiminny\Contracts\Services\Crm\Provider\SalesforceInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\ServiceUnavailableException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\AccountTransformer;
use Jiminny\Http\Transformers\ContactTransformer;
use Jiminny\Http\Transformers\LayoutTransformer;
use Jiminny\Http\Transformers\LeadTransformer;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Models\Account;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Playbook;
use Jiminny\Models\User;
use Jiminny\Rules\CrmReference;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class CrmController extends Controller
{
private const string MESSAGE_GENERAL_EXCEPTION_SEARCHING = 'Sorry, an internal error occurred whilst searching.';
private const string MESSAGE_GENERAL_EXCEPTION = 'Sorry, an internal error occurred.';
private ?ServiceInterface $crmService = null;
public function __construct(Response $response)
{
parent::__construct($response);
}
/**
* Method for searching for remote records by name.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function search(Request $request): mixed
{
$allowedScopes = [
'lead',
'account',
'contact',
'account-business',
'account-person',
'contact-business',
'contact-person',
];
$request->validate([
'scopes' => 'required|in:' . implode(',', $allowedScopes) . '|array',
'name' => 'required|string|max:100|min:2',
'limit' => 'min:1|max:20',
'offset' => 'min:0',
]);
$scopes = $request->input('scopes');
$name = $request->input('name');
$limit = $request->input('limit', 20);
$offset = $request->input('offset', 0);
$user = $this->getUserFromRequest($request);
try {
$crmService = $this->getCrmServiceWithActiveUser($user);
$crmService->setPage($limit, $offset);
$response = $crmService->find($name, $scopes);
} catch (SocialAccountTokenInvalidException $exception) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (CrmException $exception) {
$response = [];
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return $response;
}
/**
* Method for retrieving remote opportunities by account or contact.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function opportunities(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
try {
$crmProvider = $team->crm->provider;
$request->validate([
'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],
'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],
]);
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($this->request->has('contactId')) {
$contactId = $this->request->input('contactId');
$contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();
// Contact does not exist locally, import it.
if ($contact === null) {
$contact = $crmService->syncContact($contactId);
}
$accountId = $contact->account_id ? $contact->account->crm_provider_id : null;
} else {
$contactId = null;
$accountId = $this->request->input('accountId');
}
$response = $crmService->findOpportunities($accountId, $contactId, $user->getId());
} catch (\InvalidArgumentException $exception) {
$response = $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException $exception) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return $response;
}
/**
* Method for retrieving remote tasks by user.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function activities(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
$crmProvider = $team->crm->provider;
$request->validate([
'objectType' => 'in:lead,contact,account',
'prospectId' => new CrmReference($crmProvider),
'opportunityId' => new CrmReference($crmProvider),
]);
try {
$opportunityId = $request->input('opportunityId');
$objectType = $request->input('objectType');
$objectId = $request->input('prospectId');
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($objectType === null
&& $crmService instanceof SupportsObjectTypeParseInterface
) {
$objectType = $crmService->parseObjectType($objectId);
}
// Take the activity type from the Playbook (default to first for orphaned users).
if ($user->group_id) {
$playbook = $user->group->playbook;
} else {
$playbook = $user->team->playbooks()->first();
// fix empty playbook
if ($playbook === null) {
throw new \InvalidArgumentException('Please configure a Playbook first.');
}
}
if ($crmService instanceof SalesforceInterface) {
/**
* Salesforce support Tasks and Events,
* other crms support only Tasks
*/
$activities = $playbook->activity_type === Playbook::ACTIVITY_TYPE_TASK
? $crmService->getTasks($objectType, $objectId, $opportunityId)
: $crmService->getEvents($objectType, $objectId, $opportunityId);
} else {
$activities = $crmService->getTasks($objectType, $objectId, $opportunityId);
}
} catch (\InvalidArgumentException $exception) {
return $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException $exception) {
return $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
return $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
return $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return [
'activities' => $activities,
'playbookActivityType' => $playbook->activity_type,
];
}
/**
* Method for retrieving remote customer details.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function customers(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
$crmProvider = $team->crm->provider;
$request->validate([
'objectType' => 'in:lead,contact,account,opportunity,undefined',
'providerId' => new CrmReference($crmProvider),
'phoneNumber' => 'phone:INTERNATIONAL,US,' . $user->country_code,
]);
$objectType = $request->input('objectType');
$objectId = $request->input('providerId');
$phoneNumber = $request->input('phoneNumber');
$this->response
->getManager()
->setSerializer(new JsonSerializer());
try {
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($objectId) {
if (($objectType === null || $objectType === 'undefined')
&& $crmService instanceof SupportsObjectTypeParseInterface
) {
$objectType = $crmService->parseObjectType($objectId);
}
switch ($objectType) {
case 'lead':
$lead = $this->getLead($objectId);
$response = $this->response->withItem($lead, new LeadTransformer());
break;
case 'account':
$account = $this->getAccount($objectId);
$response = $this->response->withItem($account, new AccountTransformer());
break;
case 'contact':
$contact = $this->getContact($objectId);
$response = $this->response->withItem($contact, new ContactTransformer());
break;
case 'opportunity':
$opportunity = $this->getOpportunity($objectId);
$response = $this->response->withItem($opportunity->account, new AccountTransformer());
break;
default:
$response = $this->response->errorWrongArgs('Sorry, we don\'t support messaging this type of record.');
break;
}
} elseif ($phoneNumber) {
[$lead, $account, , $contact] = $crmService->matchByPhone(
$phoneNumber,
null,
$user->getId()
);
if ($lead) {
$response = $this->response->withItem($lead, new LeadTransformer());
} elseif ($account) {
$response = $this->response->withItem($account, new AccountTransformer());
} elseif ($contact) {
$response = $this->response->withItem($contact, new ContactTransformer());
} else {
$response = $this->response->errorNotFound('Customer not found.');
}
} else {
$response = $this->response->errorWrongArgs('No search data provided.');
}
} catch (\InvalidArgumentException $exception) {
$response = $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION);
}
return $response;
}
/**
* Rest method for retrieving accounts.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function accounts(): mixed
{
$user = $this->getUserFromRequest($this->request);
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'accountId' => new CrmReference($crmProvider),
]);
$this->response->getManager()->setSerializer(new JsonSerializer());
if ($this->request->has('accountId')) {
$accountId = $this->request->input('accountId');
try {
$account = $this->getAccount($accountId);
$response = $this->response->withItem($account, new AccountTransformer());
} catch (DomainException) {
$response = $this->response->errorNotFound('Record not found.');
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
} else {
$response = $this->response->withCollection($user->team->accounts, new AccountTransformer());
}
return $response;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $accountId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return Account
*/
private function getAccount(string $accountId): Account
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$account = $team->crm->accounts()->where('crm_provider_id', $accountId)->first();
if ($account instanceof Account) {
return $account;
}
// Account does not exist locally, import it.
try {
return $this->getCrmServiceWithActiveUser($user)->syncAccount($accountId);
} catch (SocialAccountTokenInvalidException $exception) {
return $this->response->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.'
);
}
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $opportunityId
*
* @throws DomainException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Opportunity
*/
private function getOpportunity(string $opportunityId): Opportunity
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if (! $opportunity instanceof Opportunity) {
$crmService = $this->getCrmServiceWithActiveUser($user);
$opportunity = $crmService->syncOpportunity($opportunityId);
}
// Sanity check.
if ($user->team_id !== $opportunity->account->team_id) {
throw new DomainException('Opportunity not found.');
}
return $opportunity;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $contactId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Contact
*/
private function getContact(string $contactId): Contact
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$crmService = $this->getCrmServiceWithActiveUser($user);
$contact = $crmService->syncContact($contactId);
}
return $contact;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $leadId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Lead
*/
private function getLead(string $leadId): Lead
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$lead = $team->crm->leads()->where('crm_provider_id', $leadId)->first();
if ($lead instanceof Lead) {
return $lead;
}
// Lead does not exist locally, import it.
return $this->getCrmServiceWithActiveUser($user)->syncLead($leadId);
}
/**
* Rest method for retrieving contacts.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function contacts(): mixed
{
$user = $this->request->user();
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],
'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],
]);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
try {
// Determine if they wish to retrieve a single contact or multiple for an account.
if ($this->request->has('contactId')) {
$contactId = $this->request->input('contactId');
$contact = $this->getContact($contactId);
$response = $this->response->withItem($contact, new ContactTransformer());
} else {
$accountId = $this->request->input('accountId');
$account = $this->getAccount($accountId);
$response = $this->response->withCollection($account->contacts, new ContactTransformer());
}
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
return $response;
}
/**
* Rest method for retrieving leads.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function leads(): mixed
{
$user = $this->request->user();
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'leadId' => new CrmReference($crmProvider),
]);
$this->response
->getManager()
->setSerializer(new JsonSerializer())
->parseIncludes(['stage', 'recordType']);
if ($this->request->has('leadId')) {
$leadId = $this->request->input('leadId');
try {
$lead = $this->getLead($leadId);
$response = $this->response->withItem($lead, new LeadTransformer());
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
} else {
$response = $this->response->withCollection($user->team->leads, new LeadTransformer());
}
return $response;
}
/**
* @param Request $request
*
* @throws ValidationException
*
* @return JsonResponse
*/
public function layouts(Request $request): JsonResponse
{
$request->validate([
'type' => 'required|in:' . implode(',', Layout::$enumTypes),
]);
$user = $request->user();
$type = $request->input('type');
// Take the activity type from the Playbook (default to first for orphaned users).
if ($user->group_id) {
$playbook = $user->group->playbook;
} else {
/** @var Playbook $playbook */
$playbook = $user->team->playbooks()->first();
}
if ($playbook === null) {
return $this->response->errorUnprocessable('Please configure a Playbook first.');
}
$layoutTypeParts = explode('-', $type);
$layoutType = sprintf(
'%s-%s',
reset($layoutTypeParts),
end($layoutTypeParts)
);
/** @var Layout|null $layout */
$layout = $playbook->layouts()
->where('name', ucfirst($playbook->activity_type) . ' Based Layout')
->where('type', $layoutType)
->first();
if ($layout === null) {
return $this->response->errorNotFound('Layout not found.');
}
$this->response
->getManager()
->setSerializer(new JsonSerializer())
->parseIncludes([
'entities.children.field.options',
]);
$transformer = new LayoutTransformer($user->crmProfile)
->setNoDefaultActivityTypeFollowUp(true)
;
return $this->response->withItem($layout, $transformer);
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmServiceWithActiveUser(User $user): ServiceInterface
{
if ($this->crmService === null) {
$team = $user->getTeam();
if (! $user->isCrmRequired()) {
$integrationAdmin = $team->getOwner();
} else {
$integrationAdmin = $user;
}
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $integrationAdmin,
'providerSlug' => $team->getCrmConfiguration()->getProviderName(),
]);
$this->crmService = $crmResolver->prepareCrmService();
}
return $this->crmService;
}
}
Execute...
|
79500
|
NULL
|
NULL
|
NULL
|
|
79500
|
2787
|
58
|
2026-05-28T06:32:03.582289+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949923582_m2.jpg...
|
PhpStorm
|
faVsco.js – CrmController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormProinet vViewNeWENNCCodeRunToolsWindowFV f PhpStormProinet vViewNeWENNCCodeRunToolsWindowFV faVsco.|s ~dolv mnotkromisein-hesder-text-rolayKeroaioh.© SyncMailbox.php© Field.phpphe api.phgCemeontrohrnhoiSF (iminny@localhost) x HS.Jocal jminny@alocalhostconedia Pere& console (EU)© BaseControlller.phpe CantTokeneontro.er.ongcomposer.jsonDockertleTextRelayServiceTest.phophp fiminny.pho2 Anv oroduetion₴.envclass CraController extends Controllenemconto trono(©) DealL evelPromotsControll© DealRiskController.oho© LanquaceController.ohooaoanaoemenonC LiveFeedController.ohoeMeeetsonoonec) Messacecontro er oho8565c) Metadatacontro er oho© MobileSettinasControllerC) Momentcontro er.ondE NudgeController.ohd2484 NumberAllocator Controlle 243E OrganizationLicensesCont 242© OrganizationRetentionPos, 244lcletenr hontd setootelcletaae hontvedthotetaparnweoatrolineoo.247© PhoneNumberController.pg PlavbackController.php@ DlavtietControllor nho© ScimController.php@ CidokiciCnntraltor nho© SoftphoneController.php© SsoController.pho© SubscriptionController.phg 349@ ToamAlAntomatinn Contrnl 35%e) ToamAlGAntoyiGAtA oESY8 ToamController phpA ToamincichteContrallornt 35%@ TranscriotionController.oh 35%C TranslationController oho 359©UserController.ohdf VocabularyController.oho>McustomerAo>Mintemsiv MKiosk>MTeams@.ActivitvController.oho8 AutomatedRenoste Controlc bachbaard eontroe.ohoclimoerconationControeo© MediaPipelineController.pld Arnaniaatione Controloe nd DortnoreContralor nhoeorntiesantraoenhrAA4RVAAV* nechod for recrteving renore rasks ou user.chrons contosnersyceneaniinten..oo*chrous Wer Found sycensnniinter.oco*cnetura miyeripublic function actávities(Request Scequest): nixedt..?* Nethod fon petrfevino racate custasen detarie• Boaran Request Srequest* Othrows ContainerExceptionInterface* Othcows NotFoundExceptionInterface* Braturn nixedpublic function customers(Request Srequest): aixedi...,* Rest nethod for retrieving accounts)* ethrows ContainerSxcentiioninterface* ethrows NotFoundExceptioninterface*ethrous Vaudattonsxceoteon* Preturn nixednublle funetion accounts(): mixedf...1* Todo: Move to a renositonu with the COM transoonpotlu ¿eoontina the recond.* Othnone ContasnerSycantsonTotanfaca* Othnone MotSoundEyconttonTotanfaca* Creturn Account2nssnodprivate function getAccount(string Saccount7d): Account....;yadhe Mud tan nandeddhen with thRoM ReRAadn denAntinn thARoRAndA console (STAGING]D000€POM activitales &=234JN users u 1.nc->1: ON aruser 3d = u.slalTEREG T E N Ủ & BI E & & E & EIDo jminny021 A1 A18 V2 Y6 Aa.status ='completedAno uurd to binc 64f1ac0-1608-4201-87126-075y079da08e=u.uusdAND a.deleted_at IS NULLSELECT 1 FROM tracks tTu fraudsos tusdeotyIDER BY a.actual_start_time DESCflect * fron crn configurations where provider = 'pipedrive"SISCTCONCAT(u.id, CASE WHEN u.id = t.ouner id THEN(ouner)" ELSE "* END) AS user idv.enail,sa.*thouner1d FROM socilal accounts s:JTN users u on uid = sa,sociable ioJTN teans t 1.nc-›1: on t5id = u.team idlJERE u,tean s1d = 19 and sa,prowider = "pioedoive":SLECT * FROM social accounts WHERE 1d = 1116%DATE sochal accounte SET onowiden usen token = *VAu:AOTBAHS-L2TNK2yuuuaLo1f2hWb9ccUNKTok4F109cinXoo 6AE0h0h00Va1nvalCHEynovS)owiden nefresh token = [TELEGRAM_TOKEN]6944446h6b2bfc*)JERE $d = 1116.provider_user-token": "viu:AQLBAH5-L2/NK2yuuuaLqifzh#b9crUNKtpk4F109minXap_6AE0hDhD0Va1nviCHEvnpvSEAAAAf:1888gkqhk169w8BBwcgMont &tmn en old vahuoc)ilect * fron crm fields where type = 'nulti-picklist':LECT * FROM Crn_ Layouts WHERE uuid_to_bin(*7C327871-4c25-4c56-9a0f-44c5a849d65c') = uuid;Sieo& conk ens louant onttoe nusos.onnloudtth202"ELECT * FROM crn fields WHERE id = 3014; # 1889SISOT & SOOM AN BOTH MOTHOG NHEOS An 31O12 12 C 791/2.TOO%L7Thu 28 May 9:32:03TextRelayServiceTestaer henseict+0.can I test it locally first. if I place env from stagingYes. The service relies on a tew thinas vou'd need in place1. Credentials file The constructor expects storage/text-relay.json (a Google service account JSON key file)Gmbtrom sthaind and oince it there2. .env values to copy from stagingGOOGLE TEXTUSERECOOGLE TEXTI HASTGOOGLE TEXT RELAY TOPIC:DEPLOY REGION:the cnail mailbox address# e.g. txt.jiminny.com or txt.staging.jiminny.com# the Pub/Sub topic namaeu or us3. Run the svnc manualiv vin tinker tinside docker 1ae 10lb bashaegdocker exec -it docker_lamp_1 php artisan tinkeapp(\Jiminny\Services\Ma1l\TextRelayService::class)-sync():Caveat: The service reads from Gmail history and dispatches jobs to the queue. If you don't want it to actuallsend SMS, make sure QUEUE_CONNECTICN»sync is not set (or use a test queue), or just call isForCurrentEnvironntioh.Ssvc = new class extends \Jiminny\Services\Mail\TextRelayService & public function _construct(som Serviceassvc-soctServicelcontiatainny.googletextI then sinsoect a eessade canual1sasg= sonailService-susers_messages-sget(config(*iminty.google text user'), *THE_MESSAGE ID*)collect(5-s0-20etPayload()-soetWeaders())-soluck("value"thut wey von can Mrit whht nandore tra nenhily oraeaet do htas macesod Calora tha ull evoc nineAsk anything (%OL)- @ eodeAdhotvMwnderhimeoeh*4 space...
|
NULL
|
2352240628453496429
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormProinet vViewNeWENNCCodeRunToolsWindowFV f PhpStormProinet vViewNeWENNCCodeRunToolsWindowFV faVsco.|s ~dolv mnotkromisein-hesder-text-rolayKeroaioh.© SyncMailbox.php© Field.phpphe api.phgCemeontrohrnhoiSF (iminny@localhost) x HS.Jocal jminny@alocalhostconedia Pere& console (EU)© BaseControlller.phpe CantTokeneontro.er.ongcomposer.jsonDockertleTextRelayServiceTest.phophp fiminny.pho2 Anv oroduetion₴.envclass CraController extends Controllenemconto trono(©) DealL evelPromotsControll© DealRiskController.oho© LanquaceController.ohooaoanaoemenonC LiveFeedController.ohoeMeeetsonoonec) Messacecontro er oho8565c) Metadatacontro er oho© MobileSettinasControllerC) Momentcontro er.ondE NudgeController.ohd2484 NumberAllocator Controlle 243E OrganizationLicensesCont 242© OrganizationRetentionPos, 244lcletenr hontd setootelcletaae hontvedthotetaparnweoatrolineoo.247© PhoneNumberController.pg PlavbackController.php@ DlavtietControllor nho© ScimController.php@ CidokiciCnntraltor nho© SoftphoneController.php© SsoController.pho© SubscriptionController.phg 349@ ToamAlAntomatinn Contrnl 35%e) ToamAlGAntoyiGAtA oESY8 ToamController phpA ToamincichteContrallornt 35%@ TranscriotionController.oh 35%C TranslationController oho 359©UserController.ohdf VocabularyController.oho>McustomerAo>Mintemsiv MKiosk>MTeams@.ActivitvController.oho8 AutomatedRenoste Controlc bachbaard eontroe.ohoclimoerconationControeo© MediaPipelineController.pld Arnaniaatione Controloe nd DortnoreContralor nhoeorntiesantraoenhrAA4RVAAV* nechod for recrteving renore rasks ou user.chrons contosnersyceneaniinten..oo*chrous Wer Found sycensnniinter.oco*cnetura miyeripublic function actávities(Request Scequest): nixedt..?* Nethod fon petrfevino racate custasen detarie• Boaran Request Srequest* Othrows ContainerExceptionInterface* Othcows NotFoundExceptionInterface* Braturn nixedpublic function customers(Request Srequest): aixedi...,* Rest nethod for retrieving accounts)* ethrows ContainerSxcentiioninterface* ethrows NotFoundExceptioninterface*ethrous Vaudattonsxceoteon* Preturn nixednublle funetion accounts(): mixedf...1* Todo: Move to a renositonu with the COM transoonpotlu ¿eoontina the recond.* Othnone ContasnerSycantsonTotanfaca* Othnone MotSoundEyconttonTotanfaca* Creturn Account2nssnodprivate function getAccount(string Saccount7d): Account....;yadhe Mud tan nandeddhen with thRoM ReRAadn denAntinn thARoRAndA console (STAGING]D000€POM activitales &=234JN users u 1.nc->1: ON aruser 3d = u.slalTEREG T E N Ủ & BI E & & E & EIDo jminny021 A1 A18 V2 Y6 Aa.status ='completedAno uurd to binc 64f1ac0-1608-4201-87126-075y079da08e=u.uusdAND a.deleted_at IS NULLSELECT 1 FROM tracks tTu fraudsos tusdeotyIDER BY a.actual_start_time DESCflect * fron crn configurations where provider = 'pipedrive"SISCTCONCAT(u.id, CASE WHEN u.id = t.ouner id THEN(ouner)" ELSE "* END) AS user idv.enail,sa.*thouner1d FROM socilal accounts s:JTN users u on uid = sa,sociable ioJTN teans t 1.nc-›1: on t5id = u.team idlJERE u,tean s1d = 19 and sa,prowider = "pioedoive":SLECT * FROM social accounts WHERE 1d = 1116%DATE sochal accounte SET onowiden usen token = *VAu:AOTBAHS-L2TNK2yuuuaLo1f2hWb9ccUNKTok4F109cinXoo 6AE0h0h00Va1nvalCHEynovS)owiden nefresh token = [TELEGRAM_TOKEN]6944446h6b2bfc*)JERE $d = 1116.provider_user-token": "viu:AQLBAH5-L2/NK2yuuuaLqifzh#b9crUNKtpk4F109minXap_6AE0hDhD0Va1nviCHEvnpvSEAAAAf:1888gkqhk169w8BBwcgMont &tmn en old vahuoc)ilect * fron crm fields where type = 'nulti-picklist':LECT * FROM Crn_ Layouts WHERE uuid_to_bin(*7C327871-4c25-4c56-9a0f-44c5a849d65c') = uuid;Sieo& conk ens louant onttoe nusos.onnloudtth202"ELECT * FROM crn fields WHERE id = 3014; # 1889SISOT & SOOM AN BOTH MOTHOG NHEOS An 31O12 12 C 791/2.TOO%L7Thu 28 May 9:32:03TextRelayServiceTestaer henseict+0.can I test it locally first. if I place env from stagingYes. The service relies on a tew thinas vou'd need in place1. Credentials file The constructor expects storage/text-relay.json (a Google service account JSON key file)Gmbtrom sthaind and oince it there2. .env values to copy from stagingGOOGLE TEXTUSERECOOGLE TEXTI HASTGOOGLE TEXT RELAY TOPIC:DEPLOY REGION:the cnail mailbox address# e.g. txt.jiminny.com or txt.staging.jiminny.com# the Pub/Sub topic namaeu or us3. Run the svnc manualiv vin tinker tinside docker 1ae 10lb bashaegdocker exec -it docker_lamp_1 php artisan tinkeapp(\Jiminny\Services\Ma1l\TextRelayService::class)-sync():Caveat: The service reads from Gmail history and dispatches jobs to the queue. If you don't want it to actuallsend SMS, make sure QUEUE_CONNECTICN»sync is not set (or use a test queue), or just call isForCurrentEnvironntioh.Ssvc = new class extends \Jiminny\Services\Mail\TextRelayService & public function _construct(som Serviceassvc-soctServicelcontiatainny.googletextI then sinsoect a eessade canual1sasg= sonailService-susers_messages-sget(config(*iminty.google text user'), *THE_MESSAGE ID*)collect(5-s0-20etPayload()-soetWeaders())-soluck("value"thut wey von can Mrit whht nandore tra nenhily oraeaet do htas macesod Calora tha ull evoc nineAsk anything (%OL)- @ eodeAdhotvMwnderhimeoeh*4 space...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79499
|
2787
|
57
|
2026-05-28T06:32:01.306320+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949921306_m2.jpg...
|
PhpStorm
|
faVsco.js – CrmController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
48
9
Previous Highlighted Error
Next Highlighted Error...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09740692,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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.8374335,"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":"TextRelayServiceTest","depth":6,"bounds":{"left":0.85272604,"top":0.019952115,"width":0.062832445,"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 'TextRelayServiceTest'","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 'TextRelayServiceTest'","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":"48","depth":4,"bounds":{"left":0.375,"top":0.10055866,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"9","depth":4,"bounds":{"left":0.38730052,"top":0.10055866,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39694148,"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.40425533,"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}]...
|
8155360477577914967
|
-8776010407387001920
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
48
9
Previous Highlighted Error
Next Highlighted Error
PhpStormEV faVscols~View$2 JY-20915-fix-missProjectvpto connect-providers.phpphe cors.phppho database.phppho datadog-helper.phppho debugbar.phppho emails-Import-filters.phppho es-mapping-settings.phppo ffmpeg.phpmiesysiems.onotdctolonwPnashids.ongwpnashing.ohowpide-helper.ohgppimaae.ongCoocKelucioTOOI-Windowphpliminny.ohpphplang.ohopholloaaind.ohpho mailiohopho men.chopho medaastreamina.oodpho prophet-al.phppto queue.phppto salesforce.phpphe saml2.phppe secure-headers.phppte sentry.phpmo services.phpme session.phpmo slack.phpmo testing-phpp umezon.oniemoview.phppp weonook"civeton› E contrib› E database> E docs› E front-end> En land> E node_modules library root> E phostan› E public>E rescurcesv Oroutespho aninhnnho console.nhome customer ani nho) Kernel.php© SyneMailbox.php© Field,phppho api.php *© CrmController,php xlaravellogSFjiminny@localhost)xA console [PROD]A console (EU]O composer.json& DockerfiieTextRelayServiceTest.phpwo jminny-phpE env.proc~fiminny/app/app/Http/Controllers/APl/CrmController.phpQ- layourx 3 Ccw.T.Y:TeAutos68 fminny ~oh actwcies021 41 418 X2 X8 ASrouter->group(['middleware' => ['auth:api']1, static function (Router Srouter): void (A11 A ~ 234Diusers u. nc-l: On aruser o = u.donanel nomecopzes an deats.copzcsTEREster-›get('/topics-in-deals/topic-triggers', [TopicsInDealsController::class, 'topicTriggers'])266o>nanel namecoozes an deats. copzc traccersiter-›get('/compare-topics-in-deals', [TopicsInDealsController: :class,"conparison"I)238>namel namecoozes an deats.conparzson239248a.status = 'completed"Ano uurd co bincc411a00-1608-4201-8726-075y079da08eeu.uusdAND a.deleted_at IS NULLANDSXTESSELECT 1 FROM tracks tWHERE t.activity_id = a.idAND t.type IN ('audio', "video')279313khacelonsster-›group(['prefix' => "crn'], static function (Router Srouter): void ‹roueroooesearchwtonrolter[CrnController::class,'opportunities')):Sroueroooedous conens etonrotrscusosensSrouten->aercontacte"."contontnottenssclass, "contacte"oi"Leads' )):Souter-›get('/tosks', [CrnController::class, 'activities')):s', [CrnContrpller::class,uts' 1):AI CRM notes.ster-›group(['prefix' »> 'ai-crn-notes'], static function (Router Srouter): void {...}):lutomated Reportsster-›post('/autonated-reports/interest', [UserAutonatedReportsController::class, 'trackInterest']):ster->groupCprerex a auconaced-repornts'middleware' => 'can:canAccessAiReports,' . User::class,static function (Router Srouter): void (..)iter->get('/features', (TeanSetupController::class,"features"));ster-›get('/tiers'. (TeanSetupController: :class, 'tiers')):merosoedenendans ieansr uetont not enereassenlendang"Di›get(*/crm-services', [TeanSetupController::class, 'cr=Senvices']):erosorconneet-orouidens" ieeue untont nottenerahss.conneer Prowidens'1r-›get('/integration-app-token', [TeanSetupController: :class,"integrationAppToken'D);meresnostaintearatton-aop=conneet tearseruatontnoe en.eoass"intearatsionAon&onnect'1)ot sicataionsster-›get('/notifications/recent', [NotificationController::class, 'notifications'l):"markAsRead"Dlster-›put('/notifications/read-nultiple', [NotificationController::class, 'narkMultipLeAsRead'I):"markAll AsRead"iiTr lanquages. (yesterday 15:44)248249200251252253259267268=269270a 3_274EDER BY a.actual_start,time DESCMIT 25:ilect * fron teans where id = 19:flect * fron crn_configurations where provider = 'Ripedcive':ELECTCONCAT(u.id, CASE WHEN U.id = t.ouner_id THEN • (onner)' ELSE ** END) AS user_id,UrehazlSa.xt.ouner_id FROM social_accounts sawusers uon urs sansodaolenIIN teans t 1.n<->1: on t.id = u.team_idIERE v.tean_id = 19 and sa.provider = 'pipedrive":FLECT * FROM social_accounts WHERE id = 1116;"DATE social_accounts SET provider_user_token = 'vlu:AQIBAHJ-L2TNK2yuuuaLq{fzhWb9crUNKTpk4FLQ9rjnXqp_6AEQh0hDQVa1nv#CHEvnpvS)ovider_refresh_token = ^5034113:195S5731:87c14258f8c813d02767ee975f6844846b6b2bfc',oines = 998919941ERE 1031516'provider_user_token": "v1u:AQIBAHJ-LzTNK2yuuuaLqifzhHb9crUNKTpk«F1Q9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfj888gkqhki69w9BBw35ilect * fron crn field values:ilect * fron crn_fields where type = 'nulti-picklist';LECT * FROM Crn_ Layouts WHERE uuid_to_bin(*7C327871-4c25-4c56-9a0f-44c5a849d65c') = uuid;ELECT * FROM crn_layout_entities WHERE crn_layout_id = 282;ELECT * FROM crn_fields WHERE id = 3014; # 1885ELECT * FROM crn_field_vatues WHERE crn_field_id = 3014;TOO%L7Thu 28 May 9:32:01U TextRelayServiceTest~aer henseict+0.can I test it locally first. if I place env from stagingYes. The service relies on a few things you'd need in place:1. Credentials file The constructor expects storage/text-relay.ison (a Google service account JSON key file)Gmbtrom sthaind and oince it there2. .env values to copy from stagingGOOGLE TEXTUSERECOOGLE TEXT HASTGOOGLE_TEXT_RELAY_TOPIC=DEPLOY _REGION=the cnail nailbox address# e.g. txt.jiminny.com or txt.staging.jiminny.com# the Pub/Sub topie name* eu or us3. Run the sync manually via tinker (inside docker_lanp_1):D bashdocker exec -it docker_lamp_1 php artisan tinker• 0app(\Jininny\ServicesVMail\TextRelayService::class)->sync();Caveat: The service reads from Gmail history and dispatches jobs to the queue. If you don't want it to actualsend SMS, make sure QUEUE_CONNECTICN-sync is not set (or use a test queue), or just call isForCurrentEnvironmtioh.Ssvc = new class extends \JiminnylServicesVa1l\TextRelayService ( public function _constructlsom Service=ssvc-soctServicelconttaminny.ooogletextI then sinsoect a eessade canual1sasg = SgnaitService-susers_gessages-sget(config(*Jiainny-9009le_text_user*), "THE_MESSAGE_ID*)collect (Sasg->getPayload()-»getHeaders())->pluck("value',thut wey von can Mrity whht handare tra nehhilm oraeset do ttat mactsod alote tha uill evoc rineAsk anything (XOL)- @ eodeAdhotvNownderehm2 4 space:...
|
79498
|
NULL
|
NULL
|
NULL
|
|
79498
|
2787
|
56
|
2026-05-28T06:32:00.335232+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949920335_m2.jpg...
|
PhpStorm
|
faVsco.js – api.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
layout
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
2/6
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Built-in Preview
Chrome
Firefox
Safari
Sync Changes
Hide This Notification
Code changed:
Hide
11
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
/**
* API routes.
*
* @see \Jiminny\Providers\RouteServiceProvider
*
* @var Router $router
*/
use Illuminate\Routing\Router;
use Illuminate\Support\Collection;
use Jiminny\Component\DealInsights\Forecast\Forecast;
use Jiminny\Component\Router\Routes;
use Jiminny\Contracts\Acl\PermissionEnum;
use Jiminny\Http\Controllers;
use Jiminny\Http\Controllers\API\ActivityController;
use Jiminny\Http\Controllers\API\AiCrmNotesController;
use Jiminny\Http\Controllers\API\ClientTokenController;
use Jiminny\Http\Controllers\API\CrmController;
use Jiminny\Http\Controllers\API\TeamInsights\TeamInsightsAiCallScoringController;
use Jiminny\Http\Controllers\ConferencesOptInOutController;
use Jiminny\Http\Controllers\API\DealRiskController;
use Jiminny\Http\Controllers\API\InstantMeetingController;
use Jiminny\Http\Controllers\API\LanguageController;
use Jiminny\Http\Controllers\API\LiveFeedController;
use Jiminny\Http\Controllers\API\MeetingsController;
use Jiminny\Http\Controllers\API\MessageController;
use Jiminny\Http\Controllers\API\MetadataController;
use Jiminny\Http\Controllers\API\MobileSettingsController;
use Jiminny\Http\Controllers\API\MomentController;
use Jiminny\Http\Controllers\API\NudgeController;
use Jiminny\Http\Controllers\API\NumberAllocatorController;
use Jiminny\Http\Controllers\API\Opportunity\CommentsController;
use Jiminny\Http\Controllers\API\OrganizationLicensesController;
use Jiminny\Http\Controllers\API\OrganizationMembersController;
use Jiminny\Http\Controllers\API\OrganizationRetentionPolicyController;
use Jiminny\Http\Controllers\API\OrganizationRolesController;
use Jiminny\Http\Controllers\API\OrganizationSyncController;
use Jiminny\Http\Controllers\API\Page\OnDemandController;
use Jiminny\Http\Controllers\API\Page\PlaybackController;
use Jiminny\Http\Controllers\API\PartnerController;
use Jiminny\Http\Controllers\API\PhoneNumberController;
use Jiminny\Http\Controllers\API\PlaylistController;
use Jiminny\Http\Controllers\API\Settings\EmailSyncController;
use Jiminny\Http\Controllers\API\SidekickController;
use Jiminny\Http\Controllers\API\SoftphoneController;
use Jiminny\Http\Controllers\API\SubscriptionController;
use Jiminny\Http\Controllers\API\TeamAiAutomationController;
use Jiminny\Http\Controllers\API\TeamAiContextController;
use Jiminny\Http\Controllers\API\TeamController;
use Jiminny\Http\Controllers\API\TeamInsights\ActivityStatsController;
use Jiminny\Http\Controllers\API\TeamInsights\CoachingFeedbacksController;
use Jiminny\Http\Controllers\API\TeamInsights\DashboardController;
use Jiminny\Http\Controllers\API\TeamInsights\EngagementController;
use Jiminny\Http\Controllers\API\TeamInsights\TeamInsightsAutomatedCallScoresController;
use Jiminny\Http\Controllers\API\TeamInsights\ThemeTopicsController;
use Jiminny\Http\Controllers\API\TeamInsights\TopicsInDealsController;
use Jiminny\Http\Controllers\API\TeamInsightsController;
use Jiminny\Http\Controllers\API\Themes\ThemeController;
use Jiminny\Http\Controllers\API\Themes\TopicController;
use Jiminny\Http\Controllers\API\Themes\TopicTriggerController;
use Jiminny\Http\Controllers\API\TranscriptionController;
use Jiminny\Http\Controllers\API\TranslationController;
use Jiminny\Http\Controllers\API\UserAutomatedReports\UserAutomatedReportsController;
use Jiminny\Http\Controllers\API\UserController;
use Jiminny\Http\Controllers\API\VocabularyController;
use Jiminny\Http\Controllers\Auth\ExtensionController;
use Jiminny\Http\Controllers\Auth\SocialController;
use Jiminny\Http\Controllers\ExportController;
use Jiminny\Http\Controllers\Kiosk\ActivityController as KioskActivityController;
use Jiminny\Http\Controllers\Kiosk\AutomatedReportsController;
use Jiminny\Http\Controllers\Kiosk\MediaPipelineController;
use Jiminny\Http\Controllers\Kiosk\OrganizationsController;
use Jiminny\Http\Controllers\Kiosk\PartnersController;
use Jiminny\Http\Controllers\Kiosk\SearchController;
use Jiminny\Http\Controllers\Kiosk\Teams\OnboardController;
use Jiminny\Http\Controllers\NotificationController;
use Jiminny\Http\Controllers\Settings\GroupController;
use Jiminny\Http\Controllers\Settings\JobTitleController;
use Jiminny\Http\Controllers\Settings\PlaybookCategoryController;
use Jiminny\Http\Controllers\Settings\PlaybookController;
use Jiminny\Http\Controllers\Settings\Teams\IntegrationController;
use Jiminny\Http\Controllers\Settings\Teams\InvitationController;
use Jiminny\Http\Controllers\Settings\Teams\TeamActivityController;
use Jiminny\Http\Controllers\Settings\Teams\TeamCoachingSettingsController;
use Jiminny\Http\Controllers\Settings\Teams\TeamConferenceSettingsController;
use Jiminny\Http\Controllers\Settings\Teams\TeamController as OrganizationController;
use Jiminny\Http\Controllers\Settings\Teams\TeamDealInsightsSettingController;
use Jiminny\Http\Controllers\Settings\Teams\TeamMemberController;
use Jiminny\Http\Controllers\Settings\Teams\TeamPhotoController;
use Jiminny\Http\Controllers\Settings\Teams\TeamRecordingSettingsController;
use Jiminny\Http\Controllers\Settings\Teams\TeamSettingsController;
use Jiminny\Http\Controllers\Settings\Teams\TeamSoftphoneSettingsController;
use Jiminny\Http\Controllers\TeamSetupController;
use Jiminny\Models;
use Jiminny\Models\PlaybackTheme;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\User;
use Jiminny\Models\Vocabulary;
use Jiminny\Repositories;
use Jiminny\Mcp\Servers\JiminnyServer;
use Laravel\Mcp\Facades\Mcp;
// mcp.audit MUST stay outermost so its $next($request) call wraps the auth
// and tier guards. Otherwise 401 (auth:api) and 403 (mcp.tier) rejections
// short-circuit before McpAuditMiddleware::handle ever runs and we lose
// audit rows for exactly the requests the security log most needs to capture.
// McpAuditMiddleware::writeAuditRow null-checks $request->user(), so writing
// pre-auth is safe.
Mcp::web('/mcp', JiminnyServer::class)
->middleware(['mcp.audit', 'auth:api', 'mcp.tier']);
$router->group(['middleware' => ['auth:api']], static function (Router $router): void {
$router->get('/metadata/extension-app', [MetadataController::class, 'extension']);
$router->get('/', [NumberAllocatorController::class, 'generate']);
$router->delete('/key-moment/{activityMoment}', [MomentController::class, 'destroy']);
$router->post('/instant-meeting/start', [InstantMeetingController::class, 'postRequestBotAtUrl'])
->middleware(['permission:' . PermissionEnum::RECORD_MEETING->value])
->name('instant-meeting.start');
// Meeting creation endpoint for Outlook add-in
$router->post('/meetings', [MeetingsController::class, 'create'])
->middleware(['permission:' . PermissionEnum::RECORD_MEETING->value])
->name('meetings.create');
// Number provisioning and search.
$router->get('/phone-numbers', [NumberAllocatorController::class, 'generate']);
$router->get('/phone-numbers/{number}', [PhoneNumberController::class, 'number']);
$router->group(['prefix' => 'deal-insights'], static function (Router $router): void {
$router->get('/forecast', [
Controllers\API\DealInsights\DealsController::class,
'getForecast',
])->defaults('period', Forecast::PERIOD_QUARTER);
$router->get('/deals/{stage?}', [
Controllers\API\DealInsights\DealsController::class,
'list',
])->defaults('stage', \Jiminny\Component\DealInsights\CriteriaInterface::STAGE_ALL);
$router->get('/details/details-daily/{opportunityId}/{date}', [
Controllers\API\DealInsights\DealsController::class,
'detailsDaily',
]);
$router->put('/deals/{opportunity}/edit-fields', [
Controllers\API\DealInsights\DealsController::class,
'updateFields',
]);
$router->get('/externalId/{dealId}', [
Controllers\API\DealInsights\DealsController::class,
'externalDealId',
]);
$router->put('/dealRisk/{dealRisk}', [DealRiskController::class, 'toggleActivity']);
});
$router->get('/team-insights/users', [TeamInsightsController::class, 'fetchUsers'])
->name('team_insights.users');
$router->get('/team-insights/dashboard', [DashboardController::class, 'fetch'])
->name('team_insights.dashboard');
// Team Insights - Coaching Feedbacks
$router->get('/team-insights/coaching-feedbacks-over-time', [CoachingFeedbacksController::class, 'fetch'])
->name('team_insights.coaching_feedbacks_over_time');
$router
->get('/team-insights/coaching-feedbacks-over-time/download', [CoachingFeedbacksController::class, 'download'])
->name('team_insights.coaching_feedbacks_over_time.download');
$router->get(
'/team-insights/coaching-feedbacks-over-time/drill-down',
[CoachingFeedbacksController::class, 'drillDown'],
)->name('team_insights.coaching_feedbacks_over_time.drill_down');
// Team Insights - Automated Call Scores
$router->get(
'/team-insights/automated-call-scores-over-time',
[TeamInsightsAutomatedCallScoresController::class, 'index'],
)->name('team_insights.automated_call_scores_over_time.index');
$router->get(
'/team-insights/automated-call-scores-over-time/drill-down',
[TeamInsightsAutomatedCallScoresController::class, 'show'],
)->name('team_insights.automated_call_scores_over_time.show');
// Team Insights - AI Call Scoring
$router->get(
'/team-insights/ai-call-scoring-over-time',
[TeamInsightsAiCallScoringController::class, 'index'],
)->name('team_insights.ai_call_scoring_over_time.index');
$router->get(
'/team-insights/ai-call-scoring-over-time/drill-down',
[TeamInsightsAiCallScoringController::class, 'show'],
)->name('team_insights.ai_call_scoring_over_time.show');
$router->get('/team-insights/engagement', [ActivityStatsController::class, 'fetch'])
->name('team_insights.engagement');
$router->get('/team-insights/engagement/drill-down/{engagementType}', [ActivityStatsController::class, 'drillDown'])
->name('team_insights.engagement.drill_down');
$router->get('/team-insights/topics', [ThemeTopicsController::class, 'getTopics'])
->name('team_insights.topics.index');
$router->get('/team-insights/topics/{topic}', [ThemeTopicsController::class, 'fetch'])
->name('team_insights.topics.show');
$router->get('/team-insights/topics/{topic}/drill-down', [ThemeTopicsController::class, 'drillDown'])
->name('team_insights.topics.drill_down');
$router->group(['prefix' => 'team-insights'], static function (Router $router): void {
$router->group(['prefix' => 'conversations'], static function (Router $router): void {
$router->get('/', [
Controllers\API\TeamInsights\ConversationsController::class,
'fetch',
]);
$router->group(['prefix' => 'drill-down'], static function (Router $router): void {
$router
->get('/{activityChannel}/{drillDownType}', [
Controllers\API\TeamInsights\ConversationsController::class,
'drillDown',
])
->where(
'activityChannel',
Collection::make(Models\Activity::CHANNELS)->join('|'),
)
->where(
'drillDownType',
Collection::make(Repositories\TeamInsightsRepository::CONVERSATION_DRILLDOWNS)
->join('|'),
);
});
});
$router->group(['prefix' => 'coaching'], static function (Router $router): void {
$router->get('/', [EngagementController::class, 'fetch']);
$router->group(['prefix' => 'drill-down'], static function (Router $router): void {
$router
->get('/{coachingType}/{drillDownType?}', [EngagementController::class, 'drillDown'])
->where(
'coachingType',
Collection::make(EngagementController::COACHING_TYPES)->join('|'),
)
->where(
'drillDownType',
Collection::make(EngagementController::COACHING_DRILLDOWNS)->join('|'),
);
});
});
});
$router->get('/topics-in-deals', [TopicsInDealsController::class, 'topics'])
->name('topics_in_deals.topics');
$router->get('/topics-in-deals/topic-triggers', [TopicsInDealsController::class, 'topicTriggers'])
->name('topics_in_deals.topic_triggers');
$router->get('/compare-topics-in-deals', [TopicsInDealsController::class, 'comparison'])
->name('topics_in_deals.comparison');
// CRM actions.
$router->group(['prefix' => 'crm'], static function (Router $router): void {
$router->get('/search', [CrmController::class, 'search']);
$router->get('/opportunity', [CrmController::class, 'opportunities']);
$router->get('/customers', [CrmController::class, 'customers']);
$router->get('/accounts', [CrmController::class, 'accounts']);
$router->get('/contacts', [CrmController::class, 'contacts']);
$router->get('/leads', [CrmController::class, 'leads']);
$router->get('/tasks', [CrmController::class, 'activities']);
$router->get('/layouts', [CrmController::class, 'layouts']);
});
// AI CRM notes.
$router->group(['prefix' => 'ai-crm-notes'], static function (Router $router): void {
$router->get('/activity/{activity}', [AiCrmNotesController::class, 'getByActivity']);
$router->post('/activity/{activity}/log-to-crm', [AiCrmNotesController::class, 'logToCrmByActivity']);
$router->post('/activity/{activity}/discard', [AiCrmNotesController::class, 'discardByActivity']);
$router->get('/deal/{opportunity}', [AiCrmNotesController::class, 'getByOpportunity']);
$router->post('/deal/{opportunity}/log-to-crm', [AiCrmNotesController::class, 'logToCrmByOpportunity']);
$router->post('/deal/{opportunity}/discard', [AiCrmNotesController::class, 'discardByOpportunity']);
});
// Automated Reports
$router->post('/automated-reports/interest', [UserAutomatedReportsController::class, 'trackInterest']);
$router->group(
[
'prefix' => 'automated-reports',
'middleware' => 'can:canAccessAiReports,' . User::class,
],
static function (Router $router): void {
$router->get('/', [UserAutomatedReportsController::class, 'list']);
$router->delete('/{uuid}', [UserAutomatedReportsController::class, 'delete']);
}
);
// Setup New Team / Trial
$router->get('/features', [TeamSetupController::class, 'features']);
$router->get('/tiers', [TeamSetupController::class, 'tiers']);
$router->get('/calendars', [TeamSetupController::class, 'calendars']);
$router->get('/crm-services', [TeamSetupController::class, 'crmServices']);
$router->get('/connect-providers', [TeamSetupController::class, 'connectProviders']);
$router->get('/integration-app-token', [TeamSetupController::class, 'integrationAppToken']);
$router->post('/integration-app-connect', [TeamSetupController::class, 'integrationAppConnect']);
// Notifications
$router->get('/notifications/recent', [NotificationController::class, 'notifications']);
$router->put('/notifications/read', [NotificationController::class, 'markAsRead']);
$router->put('/notifications/read-multiple', [NotificationController::class, 'markMultipleAsRead']);
$router->put('/notifications/read-all', [NotificationController::class, 'markAllAsRead']);
// Live feed
$router->get('/live-feed', [LiveFeedController::class, 'liveFeedItems']);
// Languages
$router->get('/languages', [LanguageController::class, 'list']);
// The whole settings section will be moved out in a separate file
$router->group(['prefix' => '/settings'], static function (Router $router): void {
$router->group(['prefix' => '/organizations'], static function (Router $router): void {
$router
->middleware(['can:kiosk,' . User::class])
->post('/', [OrganizationController::class, 'store'])
->name('kiosk.organizations.store');
$router->group(['prefix' => '{team}', 'middleware' => ['teamMember']], static function (Router $router) {
// Sync fields and team metadata
$router->post('/fields/sync', [OrganizationSyncController::class, 'index'])
->name('api.sync.fields');
// Conference Preferences.
$router->post('/bot-avatar', [TeamPhotoController::class, 'updateBotAvatar'])
->name('update.bot.avatar');
// Roles.
$router->get('/roles', [OrganizationRolesController::class, 'index'])
->name('api.roles.index');
$router->group(
['middleware' => 'permission:' . PermissionEnum::MANAGE_RETENTION_POLICY->value],
static function (Router $router): void {
$router->get('/retention-policy', [OrganizationRetentionPolicyController::class, 'index'])
->name('api.retention_policy.index');
$router->post('/retention-policy', [OrganizationRetentionPolicyController::class, 'store'])
->name('api.retention_policy.update');
}
);
$router->group(
['middleware' => 'permission:' . PermissionEnum::MANAGE_USERS->value],
static function (Router $router): void {
// Invitations.
$router->get('/invitations', [InvitationController::class, 'index'])
->name('api.invitations.index');
$router->post('/invitations/{invitation}', [InvitationController::class, 'resend'])
->name('api.invitations.resend');
$router->delete('/invitations/{invitation}', [InvitationController::class, 'destroy'])
->name('api.invitations.delete');
$router->post('/invitations', [InvitationController::class, 'store'])
->name('api.invitations.store');
},
);
$router->group(
['middleware' => 'permission:' . PermissionEnum::MANAGE_TEAM->value],
static function (Router $router): void {
// Groups.
$router->post('/groups', [GroupController::class, 'store']);
$router->get('/groups/{group}', [GroupController::class, 'show']);
$router->put('/groups/{group}', [GroupController::class, 'update']);
$router->put('/group/{group}/scope', [GroupController::class, 'updateGroupScope']);
$router->post('/group/{group}/dealRisks', [DealRiskController::class, 'updateSettings']);
// Sidekick settings
$router->group(
['middleware' => 'permission:' . PermissionEnum::MANAGE_SIDEKICK->value],
static function (Router $router): void {
$router->get('/sidekick', [SidekickController::class, 'getSidekickSettings']);
$router
->post(
'/group/{group}/sidekick',
[SidekickController::class, 'setSidekickSettings'],
)
->middleware(['can:updateSidekickSettings,group'])
->name('api.sidekick_settings.update');
$router
->post('/sidekick', [SidekickController::class, 'setSidekickSettings'])
->middleware(['permission:' . PermissionEnum::UPDATE_ALL_SIDEKICK_SETTINGS->value])
->name('api.sidekick_settings.update_all');
},
);
$router->get('/deal-insights', [TeamDealInsightsSettingController::class, 'index']);
$router->patch('/deal-insights', [TeamDealInsightsSettingController::class, 'update']);
// CRM Layout Management
$router->group(['prefix' => 'layouts'], static function (Router $router): void {
$router->get(
'/{type}',
[Controllers\API\LayoutManagementController::class, 'list'],
)->name('layouts.list');
$router->put(
'/{layout}',
[Controllers\API\LayoutManagementController::class, 'update'],
)->name('layouts.update');
});
// Users.
$router->put('/users/{user}', [TeamMemberController::class, 'update'])
->middleware(['permission:' . PermissionEnum::MANAGE_USERS->value])
->name('api.users.update');
$router->delete('/users/{user}', [TeamMemberController::class, 'deactivate'])
->middleware(['permission:' . PermissionEnum::MANAGE_USERS->value])
->name('api.users.deactivate');
$router->group(
[
'prefix' => 'vocabulary',
'middleware' => 'can:manage,' . Vocabulary::class,
],
static function (Router $router): void {
$router
->get('/', [VocabularyController::class, 'list'])
->name('api.vocabulary.index');
$router
->post('/', [VocabularyController::class, 'update'])
->name('api.vocabulary.create');
$router->group(['prefix' => '{vocabulary}'], static function (Router $router): void {
$router
->put('/', [VocabularyController::class, 'update'])
->middleware('can:update,vocabulary')
->name('api.vocabulary.update');
$router
->delete('/', [VocabularyController::class, 'delete'])
->middleware('can:delete,vocabulary')
->name('api.vocabulary.delete');
});
},
);
$router->group(['prefix' => 'ai-context'], static function (Router $router): void {
$router->get('/', [TeamAiContextController::class, 'index'])
->name('api.ai_context.get');
$router->post('/', [TeamAiContextController::class, 'store'])
->name('api.ai_context.store');
});
$router->group(['prefix' => 'ai-automation'], static function (Router $router): void {
$router->post('/fields/test-prompt', [TeamAiAutomationController::class, 'testCrmAiPrompt'])
->name('api.automation.templates.fields.test-prompt');
// List CRM fields per object type
$router->get('/fields/{objectType}', [TeamAiAutomationController::class, 'fields'])
->name('api.automation.fields');
// List DealStages fields per object type
$router->get('/stages', [TeamAiAutomationController::class, 'stages'])
->name('api.automation.stages');
// Create CRM AI template
$router->post('/templates', [TeamAiAutomationController::class, 'createTemplate'])
->name('api.automation.templates.create');
// Export CRM updates
$router->post('/templates/export-crm-updates', [TeamAiAutomationController::class, 'exportTemplateCrmUpdates'])
->name('api.automation.templates.export-crm-updates');
// Update CRM AI template
$router->put('/templates/{crmTemplate}', [TeamAiAutomationController::class, 'updateTemplate'])
->name('api.automation.templates.update');
// Delete CRM AI template
$router->delete('/templates/{crmTemplate}', [TeamAiAutomationController::class, 'deleteTemplate'])
->name('api.automation.templates.delete');
// List all CRM AI templates
$router->get('/templates', [TeamAiAutomationController::class, 'templates'])
->name('api.automation.templates.list');
// Create CRM AI template field
$router->post('/templates/{crmTemplate}/fields', [TeamAiAutomationController::class, 'createField'])
->name('api.automation.templates.fields.create');
// Update CRM AI template field
$router->put('/templates/{crmTemplate}/fields/{crmTemplateField}', [TeamAiAutomationController::class, 'updateField'])
->name('api.automation.templates.fields.update');
// Delete CRM AI template field
$router->delete('/templates/{crmTemplate}/fields/{crmTemplateField}', [TeamAiAutomationController::class, 'deleteField'])
->name('api.automation.templates.fields.delete');
});
$router->group(['prefix' => 'ai-call-scoring'], static function (Router $router): void {
// Create AI scorecard
$router->post('/ai-scorecards', [Controllers\API\AiCallScoring\AiScorecardController::class, 'createAiScorecard'])
->name('api.ai-call-scoring.ai-scorecards.create');
// Update AI scorecard
$router->put('/ai-scorecards/{aiScorecard}', [Controllers\API\AiCallScoring\AiScorecardController::class, 'updateAiScorecard'])
->name('api.ai-call-scoring.ai-scorecards.update');
// Delete AI scorecard
$router->delete('/ai-scorecards/{aiScorecard}', [Controllers\API\AiCallScoring\AiScorecardController::class, 'deleteAiScorecard'])
->name('api.ai-call-scoring.ai-scorecards.delete');
// Test AI scorecard prompt
$router->post(
'/ai-scorecards/{aiScorecard}/test-prompt',
[
Controllers\API\AiCallScoring\AiScorecardController::class,
'testAiScorecardPrompt',
]
)
->name('api.ai-call-scoring.ai-scorecards.test-prompt');
// Create AI Scorecard rule
$router->post('/ai-scorecards/{aiScorecard}/ai-scorecard-rules', [Controllers\API\AiCallScoring\AiScorecardRuleController::class, 'createRule'])
->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.create');
// Update AI Scorecard rule
$router->put('/ai-scorecards/{aiScorecard}/ai-scorecard-rules/{aiScorecardRule}', [Controllers\API\AiCallScoring\AiScorecardRuleController::class, 'updateAiScorecardRule'])
->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.update');
// Delete AI Scorecard rule
$router->delete('/ai-scorecards/{aiScorecard}/ai-scorecard-rules/{aiScorecardRule}', [Controllers\API\AiCallScoring\AiScorecardRuleController::class, 'deleteAiScorecardRule'])
->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.delete');
});
// Theme, topics, triggers
$router->get('/themes', [ThemeController::class, 'list']);
$router
->post('/themes', [ThemeController::class, 'updateTheme'])
->middleware('can:manage,' . PlaybackTheme::class)
->name('api.theme.create');
$router->group(
[
'prefix' => 'theme/{theme}',
'middleware' => 'can:update,theme',
],
static function (Router $router): void {
$router
->put('/', [ThemeController::class, 'updateTheme'])
->name('api.theme.update');
$router
->delete('/', [ThemeController::class, 'deleteTheme'])
->middleware('can:delete,theme')
->name('api.theme.delete');
$router
->post('/topics', [TopicController::class, 'updateTopic'])
->middleware('can:createTopic,theme')
->name('api.topic.create');
$router->group(
[
'prefix' => 'topic/{topic}',
'middleware' => 'can:update,topic',
],
static function (Router $router): void {
$router
->put('/', [TopicController::class, 'updateTopic'])
->name('api.topic.update');
$router
->delete('/', [TopicController::class, 'deleteTopic'])
->middleware('can:delete,topic')
->name('api.topic.delete');
$router
->post('/triggers', [TopicTriggerController::class, 'updateTrigger'])
->middleware('can:createTrigger,topic')
->name('api.topic_trigger.create');
$router->group(
[
'prefix' => 'trigger/{topicTrigger}',
'middleware' => 'can:update,topicTrigger',
],
static function (Router $router): void {
$router
->put('/', [TopicTriggerController::class, 'updateTrigger'])
->name('api.topic_trigger.update');
$router
->delete('/', [TopicTriggerController::class, 'deleteTrigger'])
->middleware('can:delete,topicTrigger')
->name('api.topic_trigger.delete');
},
);
},
);
},
);
$router->post('/themes/import', [Controllers\API\Themes\ImportTopicTriggerController::class, 'importThemes']);
$router->get('/themes/export', [Controllers\API\Themes\ExportTopicTriggerController::class, 'exportThemes']);
// Auto-scoring
$router->group(['prefix' => '/scorecards'], static function (Router $router) {
$router->get('/', [Controllers\API\Scorecards\ScorecardController::class, 'list']);
$router->post('/', [Controllers\API\Scorecards\ScorecardController::class, 'create']);
$router->delete('/{scorecard}', [
Controllers\API\Scorecards\ScorecardController::class,
'delete',
]);
$router->post('/validate-name', [
Controllers\API\Scorecards\ScorecardController::class,
'validateNameExists',
]);
$router->get('/enabled-scorecard', [
Controllers\API\Scorecards\ScorecardController::class,
'getEnabledScorecard',
]);
$router->get('/affected-scorecards', [
Controllers\API\Scorecards\ScorecardController::class,
'getAffectedScorecards',
]);
$router->group(['prefix' => '/{scorecard}'], static function (Router $router) {
$router->put('/', [
Controllers\API\Scorecards\ScorecardController::class,
'update',
]);
$router->delete('/', [
Controllers\API\Scorecards\ScorecardController::class,
'delete',
]);
$router->post('/rules', [
Controllers\API\Scorecards\ScorecardRuleController::class,
'create',
]);
$router->post('/rules/{scorecardRule}', [
Controllers\API\Scorecards\ScorecardRuleController::class,
'update',
]);
$router->delete('/rules/{scorecardRule}', [
Controllers\API\Scorecards\ScorecardRuleController::class,
'delete',
]);
$router->post('/rules/{scorecardRule}/update-order', [
Controllers\API\Scorecards\ScorecardRuleController::class,
'updateOrder',
]);
});
});
// Coaching Playbook.
Route::get('/playbooks', [PlaybookController::class, 'all']);
Route::get('/playbooksTree', [PlaybookController::class, 'tree']);
Route::put('/playbooks/{playbook}', [PlaybookController::class, 'update']);
Route::post('/playbooks', [PlaybookController::class, 'store']);
Route::delete('/playbooks/{playbook}', [PlaybookController::class, 'destroy']);
Route::prefix('/playbooks/{playbook}')->group(static function () {
// Playbook Categories.
Route::get('/categories', [PlaybookCategoryController::class, 'all']);
Route::put('/categories/sequence', [PlaybookCategoryController::class, 'sequence']); // Respect order.
Route::put('/categories/{category}', [PlaybookCategoryController::class, 'update']);
Route::post('/categories', [PlaybookCategoryController::class, 'store']);
Route::post('/test-prompt', [PlaybookController::class, 'testAiActivityTypePrompt']);
Route::post('/prompt-suggestion', [PlaybookController::class, 'getPromptSuggestion']);
Route::delete('/categories/{category}', [PlaybookCategoryController::class, 'destroy']);
Route::prefix('/categories/{category}')->group(static function () {
// Coaching Sections
Route::get('/coaching-section', [Controllers\Settings\Coaching\SectionsController::class, 'all']);
Route::put('/coaching-section/sequence', [Controllers\Settings\Coaching\SectionsController::class, 'sequence']);
Route::put('/coaching-section/{coachingSection}', [Controllers\Settings\Coaching\SectionsController::class, 'update']);
Route::post('/coaching-section', [Controllers\Settings\Coaching\SectionsController::class, 'store']);
Route::delete('/coaching-section/{coachingSection}', [Controllers\Settings\Coaching\SectionsController::class, 'destroy']);
Route::prefix('coaching-section/{coachingSection}')->group(static function () {
// Coaching Section Criteria
Route::get('/coaching-section-criterion', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'all']);
Route::put('/coaching-section-criterion/sequence', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'sequence']);
Route::put('/coaching-section-criterion/{coachingSectionCriterion}', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'update']);
Route::post('/coaching-section-criterion', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'store']);
Route::delete('/coaching-section-criterion/{coachingSectionCriterion}', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'destroy']);
});
});
});
},
);
// List all AI scorecards (accessible to all team members, no MANAGE_TEAM required)
$router->get('/ai-call-scoring/ai-scorecards', [Controllers\API\AiCallScoring\AiScorecardController::class, 'aiScorecards'])
->name('api.ai-call-scoring.ai-scorecards.list');
$router->middleware(['permission:' . PermissionEnum::MANAGE_ORGANIZATION_SETTINGS->value])
->group(static function (Router $router): void {
// Job Titles.
$router->get('/job-titles', [JobTitleController::class, 'all']);
$router->put('/job-titles/{job}', [JobTitleController::class, 'update']);
$router->post('/job-titles', [JobTitleController::class, 'store']);
$router->delete('/job-titles/{job}', [JobTitleController::class, 'destroy']);
// Team Settings.
$router->put('/', [TeamSettingsController::class, 'update']);
$router->put('/notifications', [TeamSettingsController::class, 'updateNotifications']);
$router->put('/team-conference', [TeamConferenceSettingsController::class, 'update']);
$router->put('/team-coaching', [TeamCoachingSettingsController::class, 'update']);
$router->put('/team-softphone', [TeamSoftphoneSettingsController::class, 'update']);
$router->put('/owner', [Controllers\Settings\Teams\OrganizationSettingsController::class, 'updateOwner']);
$router->put('/team-recording', [TeamRecordingSettingsController::class, 'update'])
->middleware(['permission:' . PermissionEnum::MANAGE_RECORDING->value]);
// Key Moments.
$router->get('/moments/{moment}', [Controllers\Settings\MomentController::class, 'show']);
$router->put('/moments/{moment}', [Controllers\Settings\MomentController::class, 'update']);
$router->post('/moments', [Controllers\Settings\MomentController::class, 'store']);
$router->put('/activity', [TeamActivityController::class, 'store']);
// Team Domains.
$router->get('/domains', [Controllers\Settings\Teams\TeamDomainsController::class, 'all']);
$router->post('/domains', [Controllers\Settings\Teams\TeamDomainsController::class, 'create']);
$router->delete('/domains/{teamDomain}', [Controllers\Settings\Teams\TeamDomainsController::class, 'destroy']);
});
});
});
});
// Integrations
$router->group(['middleware' => 'permission:' . PermissionEnum::MANAGE_INTEGRATIONS->value], static function (Router $router): void {
$router->post('/integrations', [IntegrationController::class, 'internal'])
->name('api.integrations.internal');
$router->put('/integrations', [IntegrationController::class, 'toggleStatus'])
->name('api.integrations.toggle_status');
$router->delete('/integrations/{provider}', [IntegrationController::class, 'delete'])
->name('api.integrations.delete');
});
$router->get('/integrations', [IntegrationController::class, 'all'])
->middleware('permission:' . PermissionEnum::READ_INTEGRATIONS->value)
->name('api.integrations.index');
// Slack API for getting slack channels list
$router->get('{notificationProvider}/channels', [Controllers\NotificationProviderController::class, 'channels']);
// Team actions. XXX: These all need moving out to their own controllers.
$router->group(['prefix' => 'organizations'], static function (Router $router): void {
$router->get('current', [TeamController::class, 'current']);
$router->group(['prefix' => '{team}', 'middleware' => ['teamMember']], static function (Router $router): void {
$router->get('/', [TeamController::class, 'show']);
$router->get('/categories', [TeamController::class, 'categories']);
$router->get('/stages', [TeamController::class, 'stages']);
$router->get('/users', [OrganizationMembersController::class, 'index'])
->name('organization.members.index');
$router
->get('/users/download', [OrganizationMembersController::class, 'download'])
->middleware('permission:' . PermissionEnum::MANAGE_USERS->value)
->name('organization.members.download');
$router->get('/licensed-roles', [OrganizationLicensesController::class, 'index'])
->middleware('permission:' . PermissionEnum::MANAGE_BILLING->value)
->name('organization.licensed-roles.index');
$router->get('/invitations', [TeamController::class, 'invitations']);
$router->get('/groups', [TeamController::class, 'groups']);
$router->delete('/groups/{group}', [TeamController::class, 'deleteGroup'])
->middleware(['permission:' . PermissionEnum::DELETE_TEAM->value])
->name('api.groups.delete');
$router->get('/job-titles', [TeamController::class, 'jobTitles']);
$router->get('/slugs', [TeamController::class, 'slugs']);
$router->put('/api-token', [TeamController::class, 'generateApiToken'])
->middleware(['permission:' . PermissionEnum::MANAGE_ORGANIZATION_SETTINGS->value]);
$router->get('/key-moments', [MomentController::class, 'all']);
});
});
// Internal Kiosk. This whole section will be moved out to a separate file
$router
->prefix('kiosk')
->middleware('can:kiosk,' . User::class)
->group(static function (Router $router): void {
// Partner actions.
$router->get('/partners', [PartnersController::class, 'index']);
// User actions.
$router->post('/users/search', [SearchController::class, 'performBasicSearch']);
// Team actions.
$router->prefix('organizations')->group(static function (Router $router): void {
$router->get('/', [OrganizationsController::class, 'show']);
$router->put('/{team}', [OrganizationController::class, 'edit'])
->name('kiosk.organizations.edit');
$router->get('/{team}/users', [OrganizationMembersController::class, 'index'])
->name('kiosk.organization.members.index');
$router->get('onboardable', [OnboardController::class, 'available']);
$router->delete('/{team}', [OrganizationsController::class, 'deactivateAccounts']);
});
// Automated reports
// api/v1/kiosk/automated-reports
$router->prefix('automated-reports')->group(static function (Router $router): void {
$router->get('/form-data', [AutomatedReportsController::class, 'getCreateForm']);
$router->get('/form-data/{reportUuid}', [AutomatedReportsController::class, 'getEditForm']);
$router->post('/filters', [AutomatedReportsController::class, 'getFilters']);
$router->post('/', [AutomatedReportsController::class, 'create']);
$router->put('/{reportUuid}', [AutomatedReportsController::class, 'update']);
$router->patch('/{reportUuid}', [AutomatedReportsController::class, 'partialUpdate']);
$router->get('/', [AutomatedReportsController::class, 'list']);
$router->get('/{reportUuid}', [AutomatedReportsController::class, 'get']);
$router->delete('/{reportUuid}', [AutomatedReportsController::class, 'delete']);
$router->post('/activities-count', [AutomatedReportsController::class, 'getActivitiesCount']);
$router->get('/{reportUuid}/reports-count', [AutomatedReportsController::class, 'getReportsCount']);
});
// Activity actions.
$router->post('/activity/search', [SearchController::class, 'performActivitySearch']);
$router->prefix('activity/{activity}')->group(static function (Router $router): void {
$router->post('check-playable', [SearchController::class, 'performActivityCheckPlayable']);
$router->post('reset-crm-log', [SearchController::class, 'performResetCrmLogActivity']);
$router->get('diarize-via-transcript', [KioskActivityController::class, 'diarizeViaTranscript']);
$router->post('diarize-via-transcript', [KioskActivityController::class, 'diarizeViaTranscript']);
$router->get('media-pipeline', [MediaPipelineController::class, 'getPipes']);
$router->post('media-pipeline', [MediaPipelineController::class, 'updatePipe']);
$router->post('language', [KioskActivityController::class, 'updateLanguage']);
$router->post('trim', [KioskActivityController::class, 'trimActivity']);
$router->get('troubleshoot', [KioskActivityController::class, 'troubleshootActivity'...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09740692,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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.8374335,"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":"TextRelayServiceTest","depth":6,"bounds":{"left":0.85272604,"top":0.019952115,"width":0.062832445,"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 'TextRelayServiceTest'","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 'TextRelayServiceTest'","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":"Show Replace Field","depth":4,"bounds":{"left":0.11868351,"top":0.105347164,"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":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.13131648,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"layout","depth":4,"bounds":{"left":0.14228724,"top":0.10454908,"width":0.043882977,"height":0.015961692},"on_screen":true,"value":"layout","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.19514628,"top":0.10454908,"width":0.00731383,"height":0.017557861},"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,"bounds":{"left":0.20511968,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"bounds":{"left":0.2137633,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"bounds":{"left":0.22240691,"top":0.10454908,"width":0.00731383,"height":0.017557861},"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.27027926,"top":1.0,"width":0.00731383,"height":0.0},"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.27027926,"top":1.0,"width":0.00731383,"height":0.0},"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.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2/6","depth":4,"bounds":{"left":0.23603724,"top":0.103751,"width":0.025598405,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.26163563,"top":0.10295291,"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":"Next Occurrence","depth":4,"bounds":{"left":0.27027926,"top":0.10295291,"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":"Filter Search Results","depth":4,"bounds":{"left":0.2789229,"top":0.10295291,"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 in Window, Multiple Cursors","depth":4,"bounds":{"left":0.28756648,"top":0.10295291,"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":"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,"bounds":{"left":0.39827126,"top":0.10295291,"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":"Built-in Preview","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":"Chrome","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":"Firefox","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":"Safari","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":"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":"11","depth":4,"bounds":{"left":0.3863032,"top":0.13407822,"width":0.008976064,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39694148,"top":0.13248204,"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.40425533,"top":0.13248204,"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\n/**\n * API routes.\n *\n * @see \\Jiminny\\Providers\\RouteServiceProvider\n *\n * @var Router $router\n */\n\nuse Illuminate\\Routing\\Router;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\DealInsights\\Forecast\\Forecast;\nuse Jiminny\\Component\\Router\\Routes;\nuse Jiminny\\Contracts\\Acl\\PermissionEnum;\nuse Jiminny\\Http\\Controllers;\nuse Jiminny\\Http\\Controllers\\API\\ActivityController;\nuse Jiminny\\Http\\Controllers\\API\\AiCrmNotesController;\nuse Jiminny\\Http\\Controllers\\API\\ClientTokenController;\nuse Jiminny\\Http\\Controllers\\API\\CrmController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\TeamInsightsAiCallScoringController;\nuse Jiminny\\Http\\Controllers\\ConferencesOptInOutController;\nuse Jiminny\\Http\\Controllers\\API\\DealRiskController;\nuse Jiminny\\Http\\Controllers\\API\\InstantMeetingController;\nuse Jiminny\\Http\\Controllers\\API\\LanguageController;\nuse Jiminny\\Http\\Controllers\\API\\LiveFeedController;\nuse Jiminny\\Http\\Controllers\\API\\MeetingsController;\nuse Jiminny\\Http\\Controllers\\API\\MessageController;\nuse Jiminny\\Http\\Controllers\\API\\MetadataController;\nuse Jiminny\\Http\\Controllers\\API\\MobileSettingsController;\nuse Jiminny\\Http\\Controllers\\API\\MomentController;\nuse Jiminny\\Http\\Controllers\\API\\NudgeController;\nuse Jiminny\\Http\\Controllers\\API\\NumberAllocatorController;\nuse Jiminny\\Http\\Controllers\\API\\Opportunity\\CommentsController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationLicensesController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationMembersController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationRetentionPolicyController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationRolesController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationSyncController;\nuse Jiminny\\Http\\Controllers\\API\\Page\\OnDemandController;\nuse Jiminny\\Http\\Controllers\\API\\Page\\PlaybackController;\nuse Jiminny\\Http\\Controllers\\API\\PartnerController;\nuse Jiminny\\Http\\Controllers\\API\\PhoneNumberController;\nuse Jiminny\\Http\\Controllers\\API\\PlaylistController;\nuse Jiminny\\Http\\Controllers\\API\\Settings\\EmailSyncController;\nuse Jiminny\\Http\\Controllers\\API\\SidekickController;\nuse Jiminny\\Http\\Controllers\\API\\SoftphoneController;\nuse Jiminny\\Http\\Controllers\\API\\SubscriptionController;\nuse Jiminny\\Http\\Controllers\\API\\TeamAiAutomationController;\nuse Jiminny\\Http\\Controllers\\API\\TeamAiContextController;\nuse Jiminny\\Http\\Controllers\\API\\TeamController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\ActivityStatsController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\CoachingFeedbacksController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\DashboardController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\EngagementController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\TeamInsightsAutomatedCallScoresController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\ThemeTopicsController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\TopicsInDealsController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsightsController;\nuse Jiminny\\Http\\Controllers\\API\\Themes\\ThemeController;\nuse Jiminny\\Http\\Controllers\\API\\Themes\\TopicController;\nuse Jiminny\\Http\\Controllers\\API\\Themes\\TopicTriggerController;\nuse Jiminny\\Http\\Controllers\\API\\TranscriptionController;\nuse Jiminny\\Http\\Controllers\\API\\TranslationController;\nuse Jiminny\\Http\\Controllers\\API\\UserAutomatedReports\\UserAutomatedReportsController;\nuse Jiminny\\Http\\Controllers\\API\\UserController;\nuse Jiminny\\Http\\Controllers\\API\\VocabularyController;\nuse Jiminny\\Http\\Controllers\\Auth\\ExtensionController;\nuse Jiminny\\Http\\Controllers\\Auth\\SocialController;\nuse Jiminny\\Http\\Controllers\\ExportController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\ActivityController as KioskActivityController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\AutomatedReportsController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\MediaPipelineController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\OrganizationsController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\PartnersController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\SearchController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\Teams\\OnboardController;\nuse Jiminny\\Http\\Controllers\\NotificationController;\nuse Jiminny\\Http\\Controllers\\Settings\\GroupController;\nuse Jiminny\\Http\\Controllers\\Settings\\JobTitleController;\nuse Jiminny\\Http\\Controllers\\Settings\\PlaybookCategoryController;\nuse Jiminny\\Http\\Controllers\\Settings\\PlaybookController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\IntegrationController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\InvitationController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamActivityController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamCoachingSettingsController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamConferenceSettingsController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamController as OrganizationController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamDealInsightsSettingController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamMemberController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamPhotoController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamRecordingSettingsController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamSettingsController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamSoftphoneSettingsController;\nuse Jiminny\\Http\\Controllers\\TeamSetupController;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\PlaybackTheme;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models\\Vocabulary;\nuse Jiminny\\Repositories;\nuse Jiminny\\Mcp\\Servers\\JiminnyServer;\nuse Laravel\\Mcp\\Facades\\Mcp;\n\n// mcp.audit MUST stay outermost so its $next($request) call wraps the auth\n// and tier guards. Otherwise 401 (auth:api) and 403 (mcp.tier) rejections\n// short-circuit before McpAuditMiddleware::handle ever runs and we lose\n// audit rows for exactly the requests the security log most needs to capture.\n// McpAuditMiddleware::writeAuditRow null-checks $request->user(), so writing\n// pre-auth is safe.\nMcp::web('/mcp', JiminnyServer::class)\n ->middleware(['mcp.audit', 'auth:api', 'mcp.tier']);\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/metadata/extension-app', [MetadataController::class, 'extension']);\n\n $router->get('/', [NumberAllocatorController::class, 'generate']);\n $router->delete('/key-moment/{activityMoment}', [MomentController::class, 'destroy']);\n\n $router->post('/instant-meeting/start', [InstantMeetingController::class, 'postRequestBotAtUrl'])\n ->middleware(['permission:' . PermissionEnum::RECORD_MEETING->value])\n ->name('instant-meeting.start');\n\n // Meeting creation endpoint for Outlook add-in\n $router->post('/meetings', [MeetingsController::class, 'create'])\n ->middleware(['permission:' . PermissionEnum::RECORD_MEETING->value])\n ->name('meetings.create');\n\n // Number provisioning and search.\n $router->get('/phone-numbers', [NumberAllocatorController::class, 'generate']);\n $router->get('/phone-numbers/{number}', [PhoneNumberController::class, 'number']);\n\n $router->group(['prefix' => 'deal-insights'], static function (Router $router): void {\n $router->get('/forecast', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'getForecast',\n ])->defaults('period', Forecast::PERIOD_QUARTER);\n\n $router->get('/deals/{stage?}', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'list',\n ])->defaults('stage', \\Jiminny\\Component\\DealInsights\\CriteriaInterface::STAGE_ALL);\n\n $router->get('/details/details-daily/{opportunityId}/{date}', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'detailsDaily',\n ]);\n\n $router->put('/deals/{opportunity}/edit-fields', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'updateFields',\n ]);\n\n $router->get('/externalId/{dealId}', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'externalDealId',\n ]);\n\n $router->put('/dealRisk/{dealRisk}', [DealRiskController::class, 'toggleActivity']);\n });\n\n $router->get('/team-insights/users', [TeamInsightsController::class, 'fetchUsers'])\n ->name('team_insights.users');\n\n $router->get('/team-insights/dashboard', [DashboardController::class, 'fetch'])\n ->name('team_insights.dashboard');\n\n // Team Insights - Coaching Feedbacks\n $router->get('/team-insights/coaching-feedbacks-over-time', [CoachingFeedbacksController::class, 'fetch'])\n ->name('team_insights.coaching_feedbacks_over_time');\n\n $router\n ->get('/team-insights/coaching-feedbacks-over-time/download', [CoachingFeedbacksController::class, 'download'])\n ->name('team_insights.coaching_feedbacks_over_time.download');\n\n $router->get(\n '/team-insights/coaching-feedbacks-over-time/drill-down',\n [CoachingFeedbacksController::class, 'drillDown'],\n )->name('team_insights.coaching_feedbacks_over_time.drill_down');\n\n // Team Insights - Automated Call Scores\n $router->get(\n '/team-insights/automated-call-scores-over-time',\n [TeamInsightsAutomatedCallScoresController::class, 'index'],\n )->name('team_insights.automated_call_scores_over_time.index');\n\n $router->get(\n '/team-insights/automated-call-scores-over-time/drill-down',\n [TeamInsightsAutomatedCallScoresController::class, 'show'],\n )->name('team_insights.automated_call_scores_over_time.show');\n\n // Team Insights - AI Call Scoring\n $router->get(\n '/team-insights/ai-call-scoring-over-time',\n [TeamInsightsAiCallScoringController::class, 'index'],\n )->name('team_insights.ai_call_scoring_over_time.index');\n\n $router->get(\n '/team-insights/ai-call-scoring-over-time/drill-down',\n [TeamInsightsAiCallScoringController::class, 'show'],\n )->name('team_insights.ai_call_scoring_over_time.show');\n\n $router->get('/team-insights/engagement', [ActivityStatsController::class, 'fetch'])\n ->name('team_insights.engagement');\n\n $router->get('/team-insights/engagement/drill-down/{engagementType}', [ActivityStatsController::class, 'drillDown'])\n ->name('team_insights.engagement.drill_down');\n\n $router->get('/team-insights/topics', [ThemeTopicsController::class, 'getTopics'])\n ->name('team_insights.topics.index');\n\n $router->get('/team-insights/topics/{topic}', [ThemeTopicsController::class, 'fetch'])\n ->name('team_insights.topics.show');\n\n $router->get('/team-insights/topics/{topic}/drill-down', [ThemeTopicsController::class, 'drillDown'])\n ->name('team_insights.topics.drill_down');\n\n $router->group(['prefix' => 'team-insights'], static function (Router $router): void {\n $router->group(['prefix' => 'conversations'], static function (Router $router): void {\n $router->get('/', [\n Controllers\\API\\TeamInsights\\ConversationsController::class,\n 'fetch',\n ]);\n\n $router->group(['prefix' => 'drill-down'], static function (Router $router): void {\n $router\n ->get('/{activityChannel}/{drillDownType}', [\n Controllers\\API\\TeamInsights\\ConversationsController::class,\n 'drillDown',\n ])\n ->where(\n 'activityChannel',\n Collection::make(Models\\Activity::CHANNELS)->join('|'),\n )\n ->where(\n 'drillDownType',\n Collection::make(Repositories\\TeamInsightsRepository::CONVERSATION_DRILLDOWNS)\n ->join('|'),\n );\n });\n });\n\n $router->group(['prefix' => 'coaching'], static function (Router $router): void {\n $router->get('/', [EngagementController::class, 'fetch']);\n\n $router->group(['prefix' => 'drill-down'], static function (Router $router): void {\n $router\n ->get('/{coachingType}/{drillDownType?}', [EngagementController::class, 'drillDown'])\n ->where(\n 'coachingType',\n Collection::make(EngagementController::COACHING_TYPES)->join('|'),\n )\n ->where(\n 'drillDownType',\n Collection::make(EngagementController::COACHING_DRILLDOWNS)->join('|'),\n );\n });\n });\n });\n\n $router->get('/topics-in-deals', [TopicsInDealsController::class, 'topics'])\n ->name('topics_in_deals.topics');\n $router->get('/topics-in-deals/topic-triggers', [TopicsInDealsController::class, 'topicTriggers'])\n ->name('topics_in_deals.topic_triggers');\n $router->get('/compare-topics-in-deals', [TopicsInDealsController::class, 'comparison'])\n ->name('topics_in_deals.comparison');\n\n // CRM actions.\n $router->group(['prefix' => 'crm'], static function (Router $router): void {\n $router->get('/search', [CrmController::class, 'search']);\n $router->get('/opportunity', [CrmController::class, 'opportunities']);\n $router->get('/customers', [CrmController::class, 'customers']);\n $router->get('/accounts', [CrmController::class, 'accounts']);\n $router->get('/contacts', [CrmController::class, 'contacts']);\n $router->get('/leads', [CrmController::class, 'leads']);\n $router->get('/tasks', [CrmController::class, 'activities']);\n $router->get('/layouts', [CrmController::class, 'layouts']);\n });\n\n // AI CRM notes.\n $router->group(['prefix' => 'ai-crm-notes'], static function (Router $router): void {\n $router->get('/activity/{activity}', [AiCrmNotesController::class, 'getByActivity']);\n $router->post('/activity/{activity}/log-to-crm', [AiCrmNotesController::class, 'logToCrmByActivity']);\n $router->post('/activity/{activity}/discard', [AiCrmNotesController::class, 'discardByActivity']);\n\n $router->get('/deal/{opportunity}', [AiCrmNotesController::class, 'getByOpportunity']);\n $router->post('/deal/{opportunity}/log-to-crm', [AiCrmNotesController::class, 'logToCrmByOpportunity']);\n $router->post('/deal/{opportunity}/discard', [AiCrmNotesController::class, 'discardByOpportunity']);\n });\n\n // Automated Reports\n $router->post('/automated-reports/interest', [UserAutomatedReportsController::class, 'trackInterest']);\n\n $router->group(\n [\n 'prefix' => 'automated-reports',\n 'middleware' => 'can:canAccessAiReports,' . User::class,\n ],\n static function (Router $router): void {\n $router->get('/', [UserAutomatedReportsController::class, 'list']);\n $router->delete('/{uuid}', [UserAutomatedReportsController::class, 'delete']);\n }\n );\n\n // Setup New Team / Trial\n $router->get('/features', [TeamSetupController::class, 'features']);\n $router->get('/tiers', [TeamSetupController::class, 'tiers']);\n $router->get('/calendars', [TeamSetupController::class, 'calendars']);\n $router->get('/crm-services', [TeamSetupController::class, 'crmServices']);\n $router->get('/connect-providers', [TeamSetupController::class, 'connectProviders']);\n $router->get('/integration-app-token', [TeamSetupController::class, 'integrationAppToken']);\n $router->post('/integration-app-connect', [TeamSetupController::class, 'integrationAppConnect']);\n\n // Notifications\n $router->get('/notifications/recent', [NotificationController::class, 'notifications']);\n $router->put('/notifications/read', [NotificationController::class, 'markAsRead']);\n $router->put('/notifications/read-multiple', [NotificationController::class, 'markMultipleAsRead']);\n $router->put('/notifications/read-all', [NotificationController::class, 'markAllAsRead']);\n\n // Live feed\n $router->get('/live-feed', [LiveFeedController::class, 'liveFeedItems']);\n\n // Languages\n $router->get('/languages', [LanguageController::class, 'list']);\n\n // The whole settings section will be moved out in a separate file\n $router->group(['prefix' => '/settings'], static function (Router $router): void {\n $router->group(['prefix' => '/organizations'], static function (Router $router): void {\n $router\n ->middleware(['can:kiosk,' . User::class])\n ->post('/', [OrganizationController::class, 'store'])\n ->name('kiosk.organizations.store');\n\n $router->group(['prefix' => '{team}', 'middleware' => ['teamMember']], static function (Router $router) {\n // Sync fields and team metadata\n $router->post('/fields/sync', [OrganizationSyncController::class, 'index'])\n ->name('api.sync.fields');\n\n // Conference Preferences.\n $router->post('/bot-avatar', [TeamPhotoController::class, 'updateBotAvatar'])\n ->name('update.bot.avatar');\n\n // Roles.\n $router->get('/roles', [OrganizationRolesController::class, 'index'])\n ->name('api.roles.index');\n\n $router->group(\n ['middleware' => 'permission:' . PermissionEnum::MANAGE_RETENTION_POLICY->value],\n static function (Router $router): void {\n $router->get('/retention-policy', [OrganizationRetentionPolicyController::class, 'index'])\n ->name('api.retention_policy.index');\n\n $router->post('/retention-policy', [OrganizationRetentionPolicyController::class, 'store'])\n ->name('api.retention_policy.update');\n }\n );\n\n $router->group(\n ['middleware' => 'permission:' . PermissionEnum::MANAGE_USERS->value],\n static function (Router $router): void {\n // Invitations.\n $router->get('/invitations', [InvitationController::class, 'index'])\n ->name('api.invitations.index');\n $router->post('/invitations/{invitation}', [InvitationController::class, 'resend'])\n ->name('api.invitations.resend');\n $router->delete('/invitations/{invitation}', [InvitationController::class, 'destroy'])\n ->name('api.invitations.delete');\n $router->post('/invitations', [InvitationController::class, 'store'])\n ->name('api.invitations.store');\n },\n );\n\n $router->group(\n ['middleware' => 'permission:' . PermissionEnum::MANAGE_TEAM->value],\n static function (Router $router): void {\n // Groups.\n $router->post('/groups', [GroupController::class, 'store']);\n $router->get('/groups/{group}', [GroupController::class, 'show']);\n $router->put('/groups/{group}', [GroupController::class, 'update']);\n\n $router->put('/group/{group}/scope', [GroupController::class, 'updateGroupScope']);\n\n $router->post('/group/{group}/dealRisks', [DealRiskController::class, 'updateSettings']);\n\n // Sidekick settings\n $router->group(\n ['middleware' => 'permission:' . PermissionEnum::MANAGE_SIDEKICK->value],\n static function (Router $router): void {\n $router->get('/sidekick', [SidekickController::class, 'getSidekickSettings']);\n $router\n ->post(\n '/group/{group}/sidekick',\n [SidekickController::class, 'setSidekickSettings'],\n )\n ->middleware(['can:updateSidekickSettings,group'])\n ->name('api.sidekick_settings.update');\n $router\n ->post('/sidekick', [SidekickController::class, 'setSidekickSettings'])\n ->middleware(['permission:' . PermissionEnum::UPDATE_ALL_SIDEKICK_SETTINGS->value])\n ->name('api.sidekick_settings.update_all');\n },\n );\n\n $router->get('/deal-insights', [TeamDealInsightsSettingController::class, 'index']);\n $router->patch('/deal-insights', [TeamDealInsightsSettingController::class, 'update']);\n\n // CRM Layout Management\n $router->group(['prefix' => 'layouts'], static function (Router $router): void {\n $router->get(\n '/{type}',\n [Controllers\\API\\LayoutManagementController::class, 'list'],\n )->name('layouts.list');\n\n $router->put(\n '/{layout}',\n [Controllers\\API\\LayoutManagementController::class, 'update'],\n )->name('layouts.update');\n });\n\n // Users.\n $router->put('/users/{user}', [TeamMemberController::class, 'update'])\n ->middleware(['permission:' . PermissionEnum::MANAGE_USERS->value])\n ->name('api.users.update');\n $router->delete('/users/{user}', [TeamMemberController::class, 'deactivate'])\n ->middleware(['permission:' . PermissionEnum::MANAGE_USERS->value])\n ->name('api.users.deactivate');\n\n $router->group(\n [\n 'prefix' => 'vocabulary',\n 'middleware' => 'can:manage,' . Vocabulary::class,\n ],\n static function (Router $router): void {\n $router\n ->get('/', [VocabularyController::class, 'list'])\n ->name('api.vocabulary.index');\n $router\n ->post('/', [VocabularyController::class, 'update'])\n ->name('api.vocabulary.create');\n\n $router->group(['prefix' => '{vocabulary}'], static function (Router $router): void {\n $router\n ->put('/', [VocabularyController::class, 'update'])\n ->middleware('can:update,vocabulary')\n ->name('api.vocabulary.update');\n $router\n ->delete('/', [VocabularyController::class, 'delete'])\n ->middleware('can:delete,vocabulary')\n ->name('api.vocabulary.delete');\n });\n },\n );\n\n $router->group(['prefix' => 'ai-context'], static function (Router $router): void {\n $router->get('/', [TeamAiContextController::class, 'index'])\n ->name('api.ai_context.get');\n $router->post('/', [TeamAiContextController::class, 'store'])\n ->name('api.ai_context.store');\n });\n\n $router->group(['prefix' => 'ai-automation'], static function (Router $router): void {\n $router->post('/fields/test-prompt', [TeamAiAutomationController::class, 'testCrmAiPrompt'])\n ->name('api.automation.templates.fields.test-prompt');\n // List CRM fields per object type\n $router->get('/fields/{objectType}', [TeamAiAutomationController::class, 'fields'])\n ->name('api.automation.fields');\n\n // List DealStages fields per object type\n $router->get('/stages', [TeamAiAutomationController::class, 'stages'])\n ->name('api.automation.stages');\n // Create CRM AI template\n $router->post('/templates', [TeamAiAutomationController::class, 'createTemplate'])\n ->name('api.automation.templates.create');\n\n // Export CRM updates\n $router->post('/templates/export-crm-updates', [TeamAiAutomationController::class, 'exportTemplateCrmUpdates'])\n ->name('api.automation.templates.export-crm-updates');\n\n // Update CRM AI template\n $router->put('/templates/{crmTemplate}', [TeamAiAutomationController::class, 'updateTemplate'])\n ->name('api.automation.templates.update');\n // Delete CRM AI template\n $router->delete('/templates/{crmTemplate}', [TeamAiAutomationController::class, 'deleteTemplate'])\n ->name('api.automation.templates.delete');\n // List all CRM AI templates\n $router->get('/templates', [TeamAiAutomationController::class, 'templates'])\n ->name('api.automation.templates.list');\n // Create CRM AI template field\n $router->post('/templates/{crmTemplate}/fields', [TeamAiAutomationController::class, 'createField'])\n ->name('api.automation.templates.fields.create');\n // Update CRM AI template field\n $router->put('/templates/{crmTemplate}/fields/{crmTemplateField}', [TeamAiAutomationController::class, 'updateField'])\n ->name('api.automation.templates.fields.update');\n // Delete CRM AI template field\n $router->delete('/templates/{crmTemplate}/fields/{crmTemplateField}', [TeamAiAutomationController::class, 'deleteField'])\n ->name('api.automation.templates.fields.delete');\n });\n\n $router->group(['prefix' => 'ai-call-scoring'], static function (Router $router): void {\n // Create AI scorecard\n $router->post('/ai-scorecards', [Controllers\\API\\AiCallScoring\\AiScorecardController::class, 'createAiScorecard'])\n ->name('api.ai-call-scoring.ai-scorecards.create');\n // Update AI scorecard\n $router->put('/ai-scorecards/{aiScorecard}', [Controllers\\API\\AiCallScoring\\AiScorecardController::class, 'updateAiScorecard'])\n ->name('api.ai-call-scoring.ai-scorecards.update');\n // Delete AI scorecard\n $router->delete('/ai-scorecards/{aiScorecard}', [Controllers\\API\\AiCallScoring\\AiScorecardController::class, 'deleteAiScorecard'])\n ->name('api.ai-call-scoring.ai-scorecards.delete');\n // Test AI scorecard prompt\n $router->post(\n '/ai-scorecards/{aiScorecard}/test-prompt',\n [\n Controllers\\API\\AiCallScoring\\AiScorecardController::class,\n 'testAiScorecardPrompt',\n ]\n )\n ->name('api.ai-call-scoring.ai-scorecards.test-prompt');\n\n // Create AI Scorecard rule\n $router->post('/ai-scorecards/{aiScorecard}/ai-scorecard-rules', [Controllers\\API\\AiCallScoring\\AiScorecardRuleController::class, 'createRule'])\n ->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.create');\n // Update AI Scorecard rule\n $router->put('/ai-scorecards/{aiScorecard}/ai-scorecard-rules/{aiScorecardRule}', [Controllers\\API\\AiCallScoring\\AiScorecardRuleController::class, 'updateAiScorecardRule'])\n ->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.update');\n // Delete AI Scorecard rule\n $router->delete('/ai-scorecards/{aiScorecard}/ai-scorecard-rules/{aiScorecardRule}', [Controllers\\API\\AiCallScoring\\AiScorecardRuleController::class, 'deleteAiScorecardRule'])\n ->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.delete');\n });\n\n // Theme, topics, triggers\n $router->get('/themes', [ThemeController::class, 'list']);\n $router\n ->post('/themes', [ThemeController::class, 'updateTheme'])\n ->middleware('can:manage,' . PlaybackTheme::class)\n ->name('api.theme.create');\n\n $router->group(\n [\n 'prefix' => 'theme/{theme}',\n 'middleware' => 'can:update,theme',\n ],\n static function (Router $router): void {\n $router\n ->put('/', [ThemeController::class, 'updateTheme'])\n ->name('api.theme.update');\n $router\n ->delete('/', [ThemeController::class, 'deleteTheme'])\n ->middleware('can:delete,theme')\n ->name('api.theme.delete');\n\n $router\n ->post('/topics', [TopicController::class, 'updateTopic'])\n ->middleware('can:createTopic,theme')\n ->name('api.topic.create');\n\n $router->group(\n [\n 'prefix' => 'topic/{topic}',\n 'middleware' => 'can:update,topic',\n ],\n static function (Router $router): void {\n $router\n ->put('/', [TopicController::class, 'updateTopic'])\n ->name('api.topic.update');\n $router\n ->delete('/', [TopicController::class, 'deleteTopic'])\n ->middleware('can:delete,topic')\n ->name('api.topic.delete');\n\n $router\n ->post('/triggers', [TopicTriggerController::class, 'updateTrigger'])\n ->middleware('can:createTrigger,topic')\n ->name('api.topic_trigger.create');\n\n $router->group(\n [\n 'prefix' => 'trigger/{topicTrigger}',\n 'middleware' => 'can:update,topicTrigger',\n ],\n static function (Router $router): void {\n $router\n ->put('/', [TopicTriggerController::class, 'updateTrigger'])\n ->name('api.topic_trigger.update');\n $router\n ->delete('/', [TopicTriggerController::class, 'deleteTrigger'])\n ->middleware('can:delete,topicTrigger')\n ->name('api.topic_trigger.delete');\n },\n );\n },\n );\n },\n );\n\n $router->post('/themes/import', [Controllers\\API\\Themes\\ImportTopicTriggerController::class, 'importThemes']);\n $router->get('/themes/export', [Controllers\\API\\Themes\\ExportTopicTriggerController::class, 'exportThemes']);\n\n // Auto-scoring\n $router->group(['prefix' => '/scorecards'], static function (Router $router) {\n $router->get('/', [Controllers\\API\\Scorecards\\ScorecardController::class, 'list']);\n $router->post('/', [Controllers\\API\\Scorecards\\ScorecardController::class, 'create']);\n $router->delete('/{scorecard}', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'delete',\n ]);\n $router->post('/validate-name', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'validateNameExists',\n ]);\n\n $router->get('/enabled-scorecard', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'getEnabledScorecard',\n ]);\n\n $router->get('/affected-scorecards', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'getAffectedScorecards',\n ]);\n\n $router->group(['prefix' => '/{scorecard}'], static function (Router $router) {\n $router->put('/', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'update',\n ]);\n $router->delete('/', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'delete',\n ]);\n\n $router->post('/rules', [\n Controllers\\API\\Scorecards\\ScorecardRuleController::class,\n 'create',\n ]);\n\n $router->post('/rules/{scorecardRule}', [\n Controllers\\API\\Scorecards\\ScorecardRuleController::class,\n 'update',\n ]);\n\n $router->delete('/rules/{scorecardRule}', [\n Controllers\\API\\Scorecards\\ScorecardRuleController::class,\n 'delete',\n ]);\n\n $router->post('/rules/{scorecardRule}/update-order', [\n Controllers\\API\\Scorecards\\ScorecardRuleController::class,\n 'updateOrder',\n ]);\n });\n });\n\n // Coaching Playbook.\n Route::get('/playbooks', [PlaybookController::class, 'all']);\n Route::get('/playbooksTree', [PlaybookController::class, 'tree']);\n Route::put('/playbooks/{playbook}', [PlaybookController::class, 'update']);\n Route::post('/playbooks', [PlaybookController::class, 'store']);\n Route::delete('/playbooks/{playbook}', [PlaybookController::class, 'destroy']);\n\n Route::prefix('/playbooks/{playbook}')->group(static function () {\n // Playbook Categories.\n Route::get('/categories', [PlaybookCategoryController::class, 'all']);\n Route::put('/categories/sequence', [PlaybookCategoryController::class, 'sequence']); // Respect order.\n Route::put('/categories/{category}', [PlaybookCategoryController::class, 'update']);\n Route::post('/categories', [PlaybookCategoryController::class, 'store']);\n Route::post('/test-prompt', [PlaybookController::class, 'testAiActivityTypePrompt']);\n Route::post('/prompt-suggestion', [PlaybookController::class, 'getPromptSuggestion']);\n Route::delete('/categories/{category}', [PlaybookCategoryController::class, 'destroy']);\n\n Route::prefix('/categories/{category}')->group(static function () {\n // Coaching Sections\n Route::get('/coaching-section', [Controllers\\Settings\\Coaching\\SectionsController::class, 'all']);\n Route::put('/coaching-section/sequence', [Controllers\\Settings\\Coaching\\SectionsController::class, 'sequence']);\n Route::put('/coaching-section/{coachingSection}', [Controllers\\Settings\\Coaching\\SectionsController::class, 'update']);\n Route::post('/coaching-section', [Controllers\\Settings\\Coaching\\SectionsController::class, 'store']);\n Route::delete('/coaching-section/{coachingSection}', [Controllers\\Settings\\Coaching\\SectionsController::class, 'destroy']);\n\n Route::prefix('coaching-section/{coachingSection}')->group(static function () {\n // Coaching Section Criteria\n Route::get('/coaching-section-criterion', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'all']);\n Route::put('/coaching-section-criterion/sequence', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'sequence']);\n Route::put('/coaching-section-criterion/{coachingSectionCriterion}', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'update']);\n Route::post('/coaching-section-criterion', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'store']);\n Route::delete('/coaching-section-criterion/{coachingSectionCriterion}', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'destroy']);\n });\n });\n });\n },\n );\n\n // List all AI scorecards (accessible to all team members, no MANAGE_TEAM required)\n $router->get('/ai-call-scoring/ai-scorecards', [Controllers\\API\\AiCallScoring\\AiScorecardController::class, 'aiScorecards'])\n ->name('api.ai-call-scoring.ai-scorecards.list');\n\n $router->middleware(['permission:' . PermissionEnum::MANAGE_ORGANIZATION_SETTINGS->value])\n ->group(static function (Router $router): void {\n // Job Titles.\n $router->get('/job-titles', [JobTitleController::class, 'all']);\n $router->put('/job-titles/{job}', [JobTitleController::class, 'update']);\n $router->post('/job-titles', [JobTitleController::class, 'store']);\n $router->delete('/job-titles/{job}', [JobTitleController::class, 'destroy']);\n\n // Team Settings.\n $router->put('/', [TeamSettingsController::class, 'update']);\n $router->put('/notifications', [TeamSettingsController::class, 'updateNotifications']);\n $router->put('/team-conference', [TeamConferenceSettingsController::class, 'update']);\n $router->put('/team-coaching', [TeamCoachingSettingsController::class, 'update']);\n $router->put('/team-softphone', [TeamSoftphoneSettingsController::class, 'update']);\n $router->put('/owner', [Controllers\\Settings\\Teams\\OrganizationSettingsController::class, 'updateOwner']);\n\n $router->put('/team-recording', [TeamRecordingSettingsController::class, 'update'])\n ->middleware(['permission:' . PermissionEnum::MANAGE_RECORDING->value]);\n\n // Key Moments.\n $router->get('/moments/{moment}', [Controllers\\Settings\\MomentController::class, 'show']);\n $router->put('/moments/{moment}', [Controllers\\Settings\\MomentController::class, 'update']);\n $router->post('/moments', [Controllers\\Settings\\MomentController::class, 'store']);\n $router->put('/activity', [TeamActivityController::class, 'store']);\n\n // Team Domains.\n $router->get('/domains', [Controllers\\Settings\\Teams\\TeamDomainsController::class, 'all']);\n $router->post('/domains', [Controllers\\Settings\\Teams\\TeamDomainsController::class, 'create']);\n $router->delete('/domains/{teamDomain}', [Controllers\\Settings\\Teams\\TeamDomainsController::class, 'destroy']);\n });\n });\n });\n });\n\n // Integrations\n $router->group(['middleware' => 'permission:' . PermissionEnum::MANAGE_INTEGRATIONS->value], static function (Router $router): void {\n $router->post('/integrations', [IntegrationController::class, 'internal'])\n ->name('api.integrations.internal');\n $router->put('/integrations', [IntegrationController::class, 'toggleStatus'])\n ->name('api.integrations.toggle_status');\n $router->delete('/integrations/{provider}', [IntegrationController::class, 'delete'])\n ->name('api.integrations.delete');\n });\n\n $router->get('/integrations', [IntegrationController::class, 'all'])\n ->middleware('permission:' . PermissionEnum::READ_INTEGRATIONS->value)\n ->name('api.integrations.index');\n\n // Slack API for getting slack channels list\n $router->get('{notificationProvider}/channels', [Controllers\\NotificationProviderController::class, 'channels']);\n\n\n // Team actions. XXX: These all need moving out to their own controllers.\n $router->group(['prefix' => 'organizations'], static function (Router $router): void {\n $router->get('current', [TeamController::class, 'current']);\n\n $router->group(['prefix' => '{team}', 'middleware' => ['teamMember']], static function (Router $router): void {\n $router->get('/', [TeamController::class, 'show']);\n\n $router->get('/categories', [TeamController::class, 'categories']);\n $router->get('/stages', [TeamController::class, 'stages']);\n $router->get('/users', [OrganizationMembersController::class, 'index'])\n ->name('organization.members.index');\n $router\n ->get('/users/download', [OrganizationMembersController::class, 'download'])\n ->middleware('permission:' . PermissionEnum::MANAGE_USERS->value)\n ->name('organization.members.download');\n $router->get('/licensed-roles', [OrganizationLicensesController::class, 'index'])\n ->middleware('permission:' . PermissionEnum::MANAGE_BILLING->value)\n ->name('organization.licensed-roles.index');\n $router->get('/invitations', [TeamController::class, 'invitations']);\n $router->get('/groups', [TeamController::class, 'groups']);\n $router->delete('/groups/{group}', [TeamController::class, 'deleteGroup'])\n ->middleware(['permission:' . PermissionEnum::DELETE_TEAM->value])\n ->name('api.groups.delete');\n $router->get('/job-titles', [TeamController::class, 'jobTitles']);\n $router->get('/slugs', [TeamController::class, 'slugs']);\n $router->put('/api-token', [TeamController::class, 'generateApiToken'])\n ->middleware(['permission:' . PermissionEnum::MANAGE_ORGANIZATION_SETTINGS->value]);\n $router->get('/key-moments', [MomentController::class, 'all']);\n });\n });\n\n // Internal Kiosk. This whole section will be moved out to a separate file\n $router\n ->prefix('kiosk')\n ->middleware('can:kiosk,' . User::class)\n ->group(static function (Router $router): void {\n // Partner actions.\n $router->get('/partners', [PartnersController::class, 'index']);\n\n // User actions.\n $router->post('/users/search', [SearchController::class, 'performBasicSearch']);\n\n // Team actions.\n $router->prefix('organizations')->group(static function (Router $router): void {\n $router->get('/', [OrganizationsController::class, 'show']);\n $router->put('/{team}', [OrganizationController::class, 'edit'])\n ->name('kiosk.organizations.edit');\n $router->get('/{team}/users', [OrganizationMembersController::class, 'index'])\n ->name('kiosk.organization.members.index');\n $router->get('onboardable', [OnboardController::class, 'available']);\n $router->delete('/{team}', [OrganizationsController::class, 'deactivateAccounts']);\n });\n\n // Automated reports\n // api/v1/kiosk/automated-reports\n $router->prefix('automated-reports')->group(static function (Router $router): void {\n $router->get('/form-data', [AutomatedReportsController::class, 'getCreateForm']);\n $router->get('/form-data/{reportUuid}', [AutomatedReportsController::class, 'getEditForm']);\n $router->post('/filters', [AutomatedReportsController::class, 'getFilters']);\n $router->post('/', [AutomatedReportsController::class, 'create']);\n $router->put('/{reportUuid}', [AutomatedReportsController::class, 'update']);\n $router->patch('/{reportUuid}', [AutomatedReportsController::class, 'partialUpdate']);\n $router->get('/', [AutomatedReportsController::class, 'list']);\n $router->get('/{reportUuid}', [AutomatedReportsController::class, 'get']);\n $router->delete('/{reportUuid}', [AutomatedReportsController::class, 'delete']);\n $router->post('/activities-count', [AutomatedReportsController::class, 'getActivitiesCount']);\n $router->get('/{reportUuid}/reports-count', [AutomatedReportsController::class, 'getReportsCount']);\n });\n\n // Activity actions.\n $router->post('/activity/search', [SearchController::class, 'performActivitySearch']);\n $router->prefix('activity/{activity}')->group(static function (Router $router): void {\n $router->post('check-playable', [SearchController::class, 'performActivityCheckPlayable']);\n $router->post('reset-crm-log', [SearchController::class, 'performResetCrmLogActivity']);\n $router->get('diarize-via-transcript', [KioskActivityController::class, 'diarizeViaTranscript']);\n $router->post('diarize-via-transcript', [KioskActivityController::class, 'diarizeViaTranscript']);\n $router->get('media-pipeline', [MediaPipelineController::class, 'getPipes']);\n $router->post('media-pipeline', [MediaPipelineController::class, 'updatePipe']);\n $router->post('language', [KioskActivityController::class, 'updateLanguage']);\n $router->post('trim', [KioskActivityController::class, 'trimActivity']);\n $router->get('troubleshoot', [KioskActivityController::class, 'troubleshootActivity']);\n $router->get('transcription', [KioskActivityController::class, 'getTranscriptions']);\n $router->post('speakers', [KioskActivityController::class, 'addSpeakers']);\n $router->post('crm-fields-fill', [KioskActivityController::class, 'crmFieldsFill']);\n $router->post('summary-highlights', [KioskActivityController::class, 'summaryHighlights']);\n });\n });\n});\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->group(['prefix' => 'events'], static function (Router $router): void {\n $router->post('authenticate', [Controllers\\PusherController::class, 'auth'])\n ->name(Routes::WEBHOOK_PUSHER_AUTH);\n });\n});\n\n$router->group(['middleware' => ['api']], static function (Router $router): void {\n $router->get('/extensions/auth', [ExtensionController::class, 'authenticate']);\n $router->get('/call-token/{team}/{participant?}', [ClientTokenController::class, 'generateToken']);\n});\n\n$router->group(['prefix' => 'user'], static function (Router $router): void {\n $router->get('chrome-extension-authentication', [ExtensionController::class, 'authenticate']);\n});\n\n$router->group(['middleware' => ['auth:api'], 'prefix' => 'sms'], static function (Router $router): void {\n $router->get('/{phoneNumber}', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'messages']);\n $router->get('/', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'messagesList']);\n $router->post('/', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'send']);\n $router->delete('/{activity}', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'redact']);\n $router->put('/{activity}', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'resend']);\n});\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/users/current', [UserController::class, 'current']);\n\n $router->get('/users/slug/{slug?}', [UserController::class, 'validateSlug']);\n\n // Profile Contact Information.\n $router->put(\n '/users/{user}/settings/profile',\n [Controllers\\Settings\\Profile\\ContactInformationController::class, 'update'],\n );\n\n $router->get('/users/{user}/email-sync-settings', [EmailSyncController::class, 'index']);\n $router->put('/users/{user}/email-sync-settings', [EmailSyncController::class, 'update']);\n\n // SMS Settings.\n $router->put('/users/{user}/settings/sms', [Controllers\\Settings\\Profile\\SmsController::class, 'update']);\n\n $router->get('/settings/timezones', [Controllers\\API\\Settings\\TimeZoneController::class, 'index'])\n ->name('settings.timezones.index');\n\n $router->put('/settings/user/deal-insights', [Controllers\\Settings\\Users\\UserSettingsController::class, 'update']);\n});\n\n$router->group(['prefix' => 'page', 'middleware' => ['api', 'auth:api']], static function () use ($router): void {\n $router->get('/playback/{activity}', [PlaybackController::class, 'show'])\n ->name('api.playback');\n $router->get('/on-demand', [OnDemandController::class, 'show'])\n ->name('api.activity.search');\n});\n\n$router->group(['prefix' => 'partners', 'middleware' => 'auth:partner-api'], static function () use ($router): void {\n $router->get('/', [PartnerController::class, 'me']);\n\n $router->group(['prefix' => 'organizations'], static function () use ($router): void {\n $router->get('/{team}', [PartnerController::class, 'fetchOrganization']);\n $router->post('/', [PartnerController::class, 'createOrganization']);\n });\n\n $router->group(['prefix' => 'groups'], static function () use ($router): void {\n $router->get('/{group}', [PartnerController::class, 'fetchGroup']);\n $router->post('/', [PartnerController::class, 'createGroup']);\n });\n\n $router->group(['prefix' => 'users'], static function () use ($router): void {\n $router->get('/{user}', [PartnerController::class, 'fetchUser']);\n $router->post('/', [PartnerController::class, 'createUser']);\n $router->delete('/{user}', [PartnerController::class, 'deactivateUser']);\n });\n\n $router->group(['prefix' => 'activities'], static function () use ($router): void {\n $router->get('/{activity}', [PartnerController::class, 'fetchActivity']);\n $router->get('/', [PartnerController::class, 'searchActivity']);\n });\n});\n\n$router->group(['prefix' => 'activity', 'middleware' => 'api'], static function () use ($router): void {\n // User only.\n $router->group(['middleware' => ['auth:api']], static function () use ($router): void {\n // Bulk delete\n $router->delete('/', [ActivityController::class, 'delete']);\n\n // Search.\n $router->get('/search', [ActivityController::class, 'search']);\n\n // All comments.\n $router->get('/comments', [ActivityController::class, 'fetchComments']);\n\n // Transcription AI\n $router->get('/{activity}/action-items', [Controllers\\API\\ActionItemsController::class, 'index']);\n $router->get('/{activity}/ai-call-scoring', [Controllers\\API\\AiCallScoring\\AiCallScoringController::class, 'index']);\n\n $router->get('/saved-search', [ActivityController::class, 'listActivitySearch'])->name('api.saved_search.index');\n $router->get('/saved-search/{search}', [ActivityController::class, 'fetchActivitySearch'])->name('api.saved_search.show');\n $router->post('/saved-search', [ActivityController::class, 'createActivitySearch'])->name('api.saved_search.create');\n $router->put('/saved-search/{search}', [ActivityController::class, 'updateActivitySearch'])->name('api.saved_search.update');\n $router->delete('/saved-search/{search}', [ActivityController::class, 'deleteActivitySearch'])->name('api.saved_search.delete');\n\n $router->post('/saved-search/{search}/nudges', [NudgeController::class, 'createAction'])->name('api.nudges.create');\n $router->put('/saved-search/{search}/nudges/{nudge}', [NudgeController::class, 'updateAction'])->name('api.nudges.update');\n $router->delete('/saved-search/{search}/nudges/{nudge}', [NudgeController::class, 'deleteAction'])->name('api.nudges.delete');\n\n // Live (coaching).\n $router->get('/live', [ActivityController::class, 'live']);\n $router->get('/{activity}/cloudfront-s3-media-keys', [ActivityController::class, 'fetchCloudFrontS3MediaKeys']);\n\n $router->post('/softphone', [SoftphoneController::class, 'create']);\n $router->put('/softphone', [SoftphoneController::class, 'createCoachParticipant']);\n $router->post('/softphone/dial', [SoftphoneController::class, 'dial']);\n $router->get('/softphone/{activity}', [SoftphoneController::class, 'fetch']);\n $router->delete('/softphone/{activity}', [SoftphoneController::class, 'endCall']);\n\n $router->post('softphone/{activity}/message', [SoftphoneController::class, 'message']);\n });\n\n // Activity actions.\n $router->group(['prefix' => '{activity}', 'middleware' => ['auth:api']], static function (Router $router): void {\n // User only.\n $router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n // Messages endpoint.\n $router->post('/message', [MessageController::class, 'message']);\n\n // Organizer actions.\n $router->put('/', [ActivityController::class, 'update']);\n $router->get('/', [ActivityController::class, 'show']);\n $router->delete('/', [ActivityController::class, 'destroy']);\n\n $router->post('/recording', [ActivityController::class, 'createRecording']);\n $router->put('/recording', [ActivityController::class, 'updateRecording']);\n $router->delete('/recording', [ActivityController::class, 'stopRecording']);\n\n $router->post('/summarize', [ActivityController::class, 'summarize']);\n\n // Sales Activity Playback action.\n $router->put('/favorite', [ActivityController::class, 'favorite']);\n $router->delete('/favorite', [ActivityController::class, 'unfavorite']);\n\n $router->put('/private', [ActivityController::class, 'markAsPrivate']);\n $router->delete('/private', [ActivityController::class, 'markAsPublic']);\n\n $router->put('/notification', [ActivityController::class, 'notify']);\n $router->delete('/notification/{notification}', [ActivityController::class, 'unnotify']);\n\n // Activity comments\n $router->put('/comment/{comment}', [ActivityController::class, 'updateComment']);\n $router->post('/comment/{comment}', [ActivityController::class, 'replyComment']);\n $router->post('/comment', [ActivityController::class, 'comment']);\n $router->delete('/comment/{comment}', [ActivityController::class, 'deleteComment']);\n $router->put('/comment/{comment}/visibility', [ActivityController::class, 'updateCommentVisibility']);\n\n $router->get('/coaching-sections', [ActivityController::class, 'coachingSections']);\n\n $router->put('/coach', [ActivityController::class, 'putCoachingFeedback']);\n $router->delete('/coach/{coachingFeedback}', [ActivityController::class, 'deleteCoachingFeedback']);\n\n $router->post('/coach-request', [ActivityController::class, 'coachRequest']);\n $router->post('/share', [ActivityController::class, 'share']);\n\n $router->post('/playlists', [ActivityController::class, 'addToPlaylist'])\n ->name('playlists.add.activity');\n\n $router->post('/key-moment', [MomentController::class, 'store']);\n\n $router->put('/play', [ActivityController::class, 'play']);\n\n $router->get('/stats', [ActivityController::class, 'stats']);\n\n $router->get('/topic-triggers', [ActivityController::class, 'fetchActivityTopicTriggers']);\n\n $router->post('/topic-triggers', [ActivityController::class, 'createActivityTopicTriggers']);\n\n $router->get('/auto-score', [Controllers\\API\\Scorecards\\AutoScoreController::class, 'getAutoScore']);\n $router->post('/auto-score', [Controllers\\API\\Scorecards\\AutoScoreController::class, 'updateAutoScore']);\n\n // Get Download link for an activity\n $router->get('/download', [Controllers\\PlaybackController::class, 'getDownloadUrl'])->name('getDownloadUrl');\n\n $router->post('/note', [ActivityController::class, 'note']);\n\n $router->post('/export', [ExportController::class, 'share'])\n ->middleware(['throttle:activity-export']);\n\n $router->post('/shareable-link', [ExportController::class, 'getShareableLink'])\n ->middleware(['throttle:activity-export-shareable-link']);\n\n $router->group(['prefix' => 'transcription'], static function (Router $router): void {\n $router->get('/', [TranscriptionController::class, 'getTranscriptionByActivity']);\n $router->get('/search', [TranscriptionController::class, 'searchAction']);\n $router->get('/download', [TranscriptionController::class, 'downloadTranscriptionByActivity'])\n ->middleware(['throttle:transcription-download']);\n $router->put('/attribution-flip/{participantA}/{participantB}', [Controllers\\API\\TranscriptionController::class, 'speakerAttributionFlip']);\n $router->put('/attribution-change/{participant}', [Controllers\\API\\TranscriptionController::class, 'speakerAttributionChange']);\n $router->get('/translation', [TranslationController::class, 'getTranslation']);\n });\n });\n });\n});\n\n$router->group(['middleware' => ['auth:api']], static function () use ($router) {\n $router->put('/subscription/{morphType}', [SubscriptionController::class, 'subscribe']);\n $router->delete('/subscription/{morphType}', [SubscriptionController::class, 'unsubscribe']);\n});\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/playlists', [PlaylistController::class, 'all'])->name('api.playlists.all');\n $router->get('/playlists/user', [PlaylistController::class, 'userPlaylists'])\n ->name('api.playlists.userPlaylists');\n $router->post('/playlists', [PlaylistController::class, 'store'])->name('api.playlists.store');\n\n $router->post('/playlists/{playlist}/share', [PlaylistController::class, 'share'])\n ->name('api.playlist.create.share');\n $router->get('/playlists/{playlist}/activities', [PlaylistController::class, 'activities'])\n ->name('api.playlist.activities');\n $router->delete('/playlists/{playlist}/shares/{playlistShare}', [PlaylistController::class, 'unshare'])\n ->name('api.playlist.unshare');\n $router->get('/playlists/{playlist}/shares', [PlaylistController::class, 'shares'])\n ->name('api.playlist.get.shares');\n $router->post('/playlists/{playlist}/lock', [PlaylistController::class, 'lock'])->name('api.playlist.lock');\n $router->post('/playlists/{playlist}/unlock', [PlaylistController::class, 'unlock'])\n ->name('api.playlist.unlock');\n $router->get(\n '/playlists/{playlist}/available-playlists',\n [PlaylistController::class, 'availablePlaylistsToMoveTo'],\n )->name('api.playlist.available');\n $router->put('/playlists/{playlist}', [PlaylistController::class, 'update'])->name('api.playlist.update');\n $router->delete('/playlists/{playlist}', [PlaylistController::class, 'destroy'])\n ->name('api.playlist.destroy');\n $router->put(\n '/playlists/{playlist}/tracks/{playlistActivity}',\n [PlaylistController::class, 'updatePlaylistTrack'],\n )->name('api.playlist.updatePlaylistTrack');\n $router->put(\n '/playlists/{playlist}/tracks/{playlistActivity}/move',\n [PlaylistController::class, 'moveToPlaylist'],\n )->name('api.playlist.moveToPlaylist');\n $router->delete(\n '/playlists/{playlist}/tracks/{playlistActivity}',\n [PlaylistController::class, 'removeFromPlaylist'],\n )->name('api.playlist.removeFromPlaylist');\n});\n\n$router->group(\n ['prefix' => '/opportunity/{opportunity}', 'middleware' => ['api']],\n static function (Router $router): void {\n // Opportunity comments\n $router->group(['prefix' => '/comment', 'middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/', [CommentsController::class, 'fetchComments']);\n $router->post('/', [CommentsController::class, 'comment']);\n\n $router->group(['prefix' => '{comment}'], static function (Router $router): void {\n $router->put('/', [CommentsController::class, 'updateComment']);\n $router->post('/', [CommentsController::class, 'replyComment']);\n $router->delete('/', [CommentsController::class, 'deleteComment']);\n $router->put('/visibility', [CommentsController::class, 'updateCommentVisibility']);\n });\n });\n },\n);\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/playlist/{activity}.m3u8', [Controllers\\API\\PlaybackController::class, 'playlist']);\n $router->get('/media/{track}.m3u8', [Controllers\\API\\PlaybackController::class, 'media']);\n});\n\n$router->group(['middleware' => ['api']], static function (Router $router): void {\n // SSO email query.\n $router->get('/auth/sso/login', [Controllers\\API\\SsoController::class, 'ssoLogin'])->name('ssoLogin');\n});\n\n$router->get('/mobile-settings', [MobileSettingsController::class, 'getAll']);\n\n$router->put('/mobile-settings', [MobileSettingsController::class, 'updateSettings'])\n ->middleware(['auth:api', 'can:kiosk,' . User::class])\n ->name('api.kiosk.mobile_settings.update');\n\n// Ask Jiminny on deal level\n$router->get('deals/{opportunity}/ask-jiminny', [Controllers\\API\\DealLevelPromptsController::class, 'index'])\n ->middleware(['api', 'auth:api'])\n ->name('api.deals.ask-jiminny');\n\n$router->get('get-access-token/{provider?}', [SocialController::class, 'getAccessToken'])\n ->name('api.get_access_token')\n ->whereIn('provider', [SocialAccount::PROVIDER_HUBSPOT]);\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->post('single-claim-token/{provider?}', [SocialController::class, 'getSingleUseClaim'])\n ->name('api.singe-claim-token');\n});\n\n$router->post('deauthorize-zoom-app', [SocialController::class, 'deauthorizeZoomApp'])\n ->name('api.deauthorize-zoom-app.recall-ai');\n\n$router->put('/conferences/{activity}/consent', [ConferencesOptInOutController::class, 'storeConsent'])\n ->middleware(['throttle:conference-consent'])\n ->name('api.conferences.store-consent');","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\n/**\n * API routes.\n *\n * @see \\Jiminny\\Providers\\RouteServiceProvider\n *\n * @var Router $router\n */\n\nuse Illuminate\\Routing\\Router;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\DealInsights\\Forecast\\Forecast;\nuse Jiminny\\Component\\Router\\Routes;\nuse Jiminny\\Contracts\\Acl\\PermissionEnum;\nuse Jiminny\\Http\\Controllers;\nuse Jiminny\\Http\\Controllers\\API\\ActivityController;\nuse Jiminny\\Http\\Controllers\\API\\AiCrmNotesController;\nuse Jiminny\\Http\\Controllers\\API\\ClientTokenController;\nuse Jiminny\\Http\\Controllers\\API\\CrmController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\TeamInsightsAiCallScoringController;\nuse Jiminny\\Http\\Controllers\\ConferencesOptInOutController;\nuse Jiminny\\Http\\Controllers\\API\\DealRiskController;\nuse Jiminny\\Http\\Controllers\\API\\InstantMeetingController;\nuse Jiminny\\Http\\Controllers\\API\\LanguageController;\nuse Jiminny\\Http\\Controllers\\API\\LiveFeedController;\nuse Jiminny\\Http\\Controllers\\API\\MeetingsController;\nuse Jiminny\\Http\\Controllers\\API\\MessageController;\nuse Jiminny\\Http\\Controllers\\API\\MetadataController;\nuse Jiminny\\Http\\Controllers\\API\\MobileSettingsController;\nuse Jiminny\\Http\\Controllers\\API\\MomentController;\nuse Jiminny\\Http\\Controllers\\API\\NudgeController;\nuse Jiminny\\Http\\Controllers\\API\\NumberAllocatorController;\nuse Jiminny\\Http\\Controllers\\API\\Opportunity\\CommentsController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationLicensesController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationMembersController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationRetentionPolicyController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationRolesController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationSyncController;\nuse Jiminny\\Http\\Controllers\\API\\Page\\OnDemandController;\nuse Jiminny\\Http\\Controllers\\API\\Page\\PlaybackController;\nuse Jiminny\\Http\\Controllers\\API\\PartnerController;\nuse Jiminny\\Http\\Controllers\\API\\PhoneNumberController;\nuse Jiminny\\Http\\Controllers\\API\\PlaylistController;\nuse Jiminny\\Http\\Controllers\\API\\Settings\\EmailSyncController;\nuse Jiminny\\Http\\Controllers\\API\\SidekickController;\nuse Jiminny\\Http\\Controllers\\API\\SoftphoneController;\nuse Jiminny\\Http\\Controllers\\API\\SubscriptionController;\nuse Jiminny\\Http\\Controllers\\API\\TeamAiAutomationController;\nuse Jiminny\\Http\\Controllers\\API\\TeamAiContextController;\nuse Jiminny\\Http\\Controllers\\API\\TeamController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\ActivityStatsController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\CoachingFeedbacksController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\DashboardController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\EngagementController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\TeamInsightsAutomatedCallScoresController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\ThemeTopicsController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\TopicsInDealsController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsightsController;\nuse Jiminny\\Http\\Controllers\\API\\Themes\\ThemeController;\nuse Jiminny\\Http\\Controllers\\API\\Themes\\TopicController;\nuse Jiminny\\Http\\Controllers\\API\\Themes\\TopicTriggerController;\nuse Jiminny\\Http\\Controllers\\API\\TranscriptionController;\nuse Jiminny\\Http\\Controllers\\API\\TranslationController;\nuse Jiminny\\Http\\Controllers\\API\\UserAutomatedReports\\UserAutomatedReportsController;\nuse Jiminny\\Http\\Controllers\\API\\UserController;\nuse Jiminny\\Http\\Controllers\\API\\VocabularyController;\nuse Jiminny\\Http\\Controllers\\Auth\\ExtensionController;\nuse Jiminny\\Http\\Controllers\\Auth\\SocialController;\nuse Jiminny\\Http\\Controllers\\ExportController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\ActivityController as KioskActivityController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\AutomatedReportsController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\MediaPipelineController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\OrganizationsController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\PartnersController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\SearchController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\Teams\\OnboardController;\nuse Jiminny\\Http\\Controllers\\NotificationController;\nuse Jiminny\\Http\\Controllers\\Settings\\GroupController;\nuse Jiminny\\Http\\Controllers\\Settings\\JobTitleController;\nuse Jiminny\\Http\\Controllers\\Settings\\PlaybookCategoryController;\nuse Jiminny\\Http\\Controllers\\Settings\\PlaybookController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\IntegrationController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\InvitationController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamActivityController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamCoachingSettingsController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamConferenceSettingsController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamController as OrganizationController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamDealInsightsSettingController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamMemberController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamPhotoController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamRecordingSettingsController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamSettingsController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamSoftphoneSettingsController;\nuse Jiminny\\Http\\Controllers\\TeamSetupController;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\PlaybackTheme;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models\\Vocabulary;\nuse Jiminny\\Repositories;\nuse Jiminny\\Mcp\\Servers\\JiminnyServer;\nuse Laravel\\Mcp\\Facades\\Mcp;\n\n// mcp.audit MUST stay outermost so its $next($request) call wraps the auth\n// and tier guards. Otherwise 401 (auth:api) and 403 (mcp.tier) rejections\n// short-circuit before McpAuditMiddleware::handle ever runs and we lose\n// audit rows for exactly the requests the security log most needs to capture.\n// McpAuditMiddleware::writeAuditRow null-checks $request->user(), so writing\n// pre-auth is safe.\nMcp::web('/mcp', JiminnyServer::class)\n ->middleware(['mcp.audit', 'auth:api', 'mcp.tier']);\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/metadata/extension-app', [MetadataController::class, 'extension']);\n\n $router->get('/', [NumberAllocatorController::class, 'generate']);\n $router->delete('/key-moment/{activityMoment}', [MomentController::class, 'destroy']);\n\n $router->post('/instant-meeting/start', [InstantMeetingController::class, 'postRequestBotAtUrl'])\n ->middleware(['permission:' . PermissionEnum::RECORD_MEETING->value])\n ->name('instant-meeting.start');\n\n // Meeting creation endpoint for Outlook add-in\n $router->post('/meetings', [MeetingsController::class, 'create'])\n ->middleware(['permission:' . PermissionEnum::RECORD_MEETING->value])\n ->name('meetings.create');\n\n // Number provisioning and search.\n $router->get('/phone-numbers', [NumberAllocatorController::class, 'generate']);\n $router->get('/phone-numbers/{number}', [PhoneNumberController::class, 'number']);\n\n $router->group(['prefix' => 'deal-insights'], static function (Router $router): void {\n $router->get('/forecast', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'getForecast',\n ])->defaults('period', Forecast::PERIOD_QUARTER);\n\n $router->get('/deals/{stage?}', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'list',\n ])->defaults('stage', \\Jiminny\\Component\\DealInsights\\CriteriaInterface::STAGE_ALL);\n\n $router->get('/details/details-daily/{opportunityId}/{date}', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'detailsDaily',\n ]);\n\n $router->put('/deals/{opportunity}/edit-fields', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'updateFields',\n ]);\n\n $router->get('/externalId/{dealId}', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'externalDealId',\n ]);\n\n $router->put('/dealRisk/{dealRisk}', [DealRiskController::class, 'toggleActivity']);\n });\n\n $router->get('/team-insights/users', [TeamInsightsController::class, 'fetchUsers'])\n ->name('team_insights.users');\n\n $router->get('/team-insights/dashboard', [DashboardController::class, 'fetch'])\n ->name('team_insights.dashboard');\n\n // Team Insights - Coaching Feedbacks\n $router->get('/team-insights/coaching-feedbacks-over-time', [CoachingFeedbacksController::class, 'fetch'])\n ->name('team_insights.coaching_feedbacks_over_time');\n\n $router\n ->get('/team-insights/coaching-feedbacks-over-time/download', [CoachingFeedbacksController::class, 'download'])\n ->name('team_insights.coaching_feedbacks_over_time.download');\n\n $router->get(\n '/team-insights/coaching-feedbacks-over-time/drill-down',\n [CoachingFeedbacksController::class, 'drillDown'],\n )->name('team_insights.coaching_feedbacks_over_time.drill_down');\n\n // Team Insights - Automated Call Scores\n $router->get(\n '/team-insights/automated-call-scores-over-time',\n [TeamInsightsAutomatedCallScoresController::class, 'index'],\n )->name('team_insights.automated_call_scores_over_time.index');\n\n $router->get(\n '/team-insights/automated-call-scores-over-time/drill-down',\n [TeamInsightsAutomatedCallScoresController::class, 'show'],\n )->name('team_insights.automated_call_scores_over_time.show');\n\n // Team Insights - AI Call Scoring\n $router->get(\n '/team-insights/ai-call-scoring-over-time',\n [TeamInsightsAiCallScoringController::class, 'index'],\n )->name('team_insights.ai_call_scoring_over_time.index');\n\n $router->get(\n '/team-insights/ai-call-scoring-over-time/drill-down',\n [TeamInsightsAiCallScoringController::class, 'show'],\n )->name('team_insights.ai_call_scoring_over_time.show');\n\n $router->get('/team-insights/engagement', [ActivityStatsController::class, 'fetch'])\n ->name('team_insights.engagement');\n\n $router->get('/team-insights/engagement/drill-down/{engagementType}', [ActivityStatsController::class, 'drillDown'])\n ->name('team_insights.engagement.drill_down');\n\n $router->get('/team-insights/topics', [ThemeTopicsController::class, 'getTopics'])\n ->name('team_insights.topics.index');\n\n $router->get('/team-insights/topics/{topic}', [ThemeTopicsController::class, 'fetch'])\n ->name('team_insights.topics.show');\n\n $router->get('/team-insights/topics/{topic}/drill-down', [ThemeTopicsController::class, 'drillDown'])\n ->name('team_insights.topics.drill_down');\n\n $router->group(['prefix' => 'team-insights'], static function (Router $router): void {\n $router->group(['prefix' => 'conversations'], static function (Router $router): void {\n $router->get('/', [\n Controllers\\API\\TeamInsights\\ConversationsController::class,\n 'fetch',\n ]);\n\n $router->group(['prefix' => 'drill-down'], static function (Router $router): void {\n $router\n ->get('/{activityChannel}/{drillDownType}', [\n Controllers\\API\\TeamInsights\\ConversationsController::class,\n 'drillDown',\n ])\n ->where(\n 'activityChannel',\n Collection::make(Models\\Activity::CHANNELS)->join('|'),\n )\n ->where(\n 'drillDownType',\n Collection::make(Repositories\\TeamInsightsRepository::CONVERSATION_DRILLDOWNS)\n ->join('|'),\n );\n });\n });\n\n $router->group(['prefix' => 'coaching'], static function (Router $router): void {\n $router->get('/', [EngagementController::class, 'fetch']);\n\n $router->group(['prefix' => 'drill-down'], static function (Router $router): void {\n $router\n ->get('/{coachingType}/{drillDownType?}', [EngagementController::class, 'drillDown'])\n ->where(\n 'coachingType',\n Collection::make(EngagementController::COACHING_TYPES)->join('|'),\n )\n ->where(\n 'drillDownType',\n Collection::make(EngagementController::COACHING_DRILLDOWNS)->join('|'),\n );\n });\n });\n });\n\n $router->get('/topics-in-deals', [TopicsInDealsController::class, 'topics'])\n ->name('topics_in_deals.topics');\n $router->get('/topics-in-deals/topic-triggers', [TopicsInDealsController::class, 'topicTriggers'])\n ->name('topics_in_deals.topic_triggers');\n $router->get('/compare-topics-in-deals', [TopicsInDealsController::class, 'comparison'])\n ->name('topics_in_deals.comparison');\n\n // CRM actions.\n $router->group(['prefix' => 'crm'], static function (Router $router): void {\n $router->get('/search', [CrmController::class, 'search']);\n $router->get('/opportunity', [CrmController::class, 'opportunities']);\n $router->get('/customers', [CrmController::class, 'customers']);\n $router->get('/accounts', [CrmController::class, 'accounts']);\n $router->get('/contacts', [CrmController::class, 'contacts']);\n $router->get('/leads', [CrmController::class, 'leads']);\n $router->get('/tasks', [CrmController::class, 'activities']);\n $router->get('/layouts', [CrmController::class, 'layouts']);\n });\n\n // AI CRM notes.\n $router->group(['prefix' => 'ai-crm-notes'], static function (Router $router): void {\n $router->get('/activity/{activity}', [AiCrmNotesController::class, 'getByActivity']);\n $router->post('/activity/{activity}/log-to-crm', [AiCrmNotesController::class, 'logToCrmByActivity']);\n $router->post('/activity/{activity}/discard', [AiCrmNotesController::class, 'discardByActivity']);\n\n $router->get('/deal/{opportunity}', [AiCrmNotesController::class, 'getByOpportunity']);\n $router->post('/deal/{opportunity}/log-to-crm', [AiCrmNotesController::class, 'logToCrmByOpportunity']);\n $router->post('/deal/{opportunity}/discard', [AiCrmNotesController::class, 'discardByOpportunity']);\n });\n\n // Automated Reports\n $router->post('/automated-reports/interest', [UserAutomatedReportsController::class, 'trackInterest']);\n\n $router->group(\n [\n 'prefix' => 'automated-reports',\n 'middleware' => 'can:canAccessAiReports,' . User::class,\n ],\n static function (Router $router): void {\n $router->get('/', [UserAutomatedReportsController::class, 'list']);\n $router->delete('/{uuid}', [UserAutomatedReportsController::class, 'delete']);\n }\n );\n\n // Setup New Team / Trial\n $router->get('/features', [TeamSetupController::class, 'features']);\n $router->get('/tiers', [TeamSetupController::class, 'tiers']);\n $router->get('/calendars', [TeamSetupController::class, 'calendars']);\n $router->get('/crm-services', [TeamSetupController::class, 'crmServices']);\n $router->get('/connect-providers', [TeamSetupController::class, 'connectProviders']);\n $router->get('/integration-app-token', [TeamSetupController::class, 'integrationAppToken']);\n $router->post('/integration-app-connect', [TeamSetupController::class, 'integrationAppConnect']);\n\n // Notifications\n $router->get('/notifications/recent', [NotificationController::class, 'notifications']);\n $router->put('/notifications/read', [NotificationController::class, 'markAsRead']);\n $router->put('/notifications/read-multiple', [NotificationController::class, 'markMultipleAsRead']);\n $router->put('/notifications/read-all', [NotificationController::class, 'markAllAsRead']);\n\n // Live feed\n $router->get('/live-feed', [LiveFeedController::class, 'liveFeedItems']);\n\n // Languages\n $router->get('/languages', [LanguageController::class, 'list']);\n\n // The whole settings section will be moved out in a separate file\n $router->group(['prefix' => '/settings'], static function (Router $router): void {\n $router->group(['prefix' => '/organizations'], static function (Router $router): void {\n $router\n ->middleware(['can:kiosk,' . User::class])\n ->post('/', [OrganizationController::class, 'store'])\n ->name('kiosk.organizations.store');\n\n $router->group(['prefix' => '{team}', 'middleware' => ['teamMember']], static function (Router $router) {\n // Sync fields and team metadata\n $router->post('/fields/sync', [OrganizationSyncController::class, 'index'])\n ->name('api.sync.fields');\n\n // Conference Preferences.\n $router->post('/bot-avatar', [TeamPhotoController::class, 'updateBotAvatar'])\n ->name('update.bot.avatar');\n\n // Roles.\n $router->get('/roles', [OrganizationRolesController::class, 'index'])\n ->name('api.roles.index');\n\n $router->group(\n ['middleware' => 'permission:' . PermissionEnum::MANAGE_RETENTION_POLICY->value],\n static function (Router $router): void {\n $router->get('/retention-policy', [OrganizationRetentionPolicyController::class, 'index'])\n ->name('api.retention_policy.index');\n\n $router->post('/retention-policy', [OrganizationRetentionPolicyController::class, 'store'])\n ->name('api.retention_policy.update');\n }\n );\n\n $router->group(\n ['middleware' => 'permission:' . PermissionEnum::MANAGE_USERS->value],\n static function (Router $router): void {\n // Invitations.\n $router->get('/invitations', [InvitationController::class, 'index'])\n ->name('api.invitations.index');\n $router->post('/invitations/{invitation}', [InvitationController::class, 'resend'])\n ->name('api.invitations.resend');\n $router->delete('/invitations/{invitation}', [InvitationController::class, 'destroy'])\n ->name('api.invitations.delete');\n $router->post('/invitations', [InvitationController::class, 'store'])\n ->name('api.invitations.store');\n },\n );\n\n $router->group(\n ['middleware' => 'permission:' . PermissionEnum::MANAGE_TEAM->value],\n static function (Router $router): void {\n // Groups.\n $router->post('/groups', [GroupController::class, 'store']);\n $router->get('/groups/{group}', [GroupController::class, 'show']);\n $router->put('/groups/{group}', [GroupController::class, 'update']);\n\n $router->put('/group/{group}/scope', [GroupController::class, 'updateGroupScope']);\n\n $router->post('/group/{group}/dealRisks', [DealRiskController::class, 'updateSettings']);\n\n // Sidekick settings\n $router->group(\n ['middleware' => 'permission:' . PermissionEnum::MANAGE_SIDEKICK->value],\n static function (Router $router): void {\n $router->get('/sidekick', [SidekickController::class, 'getSidekickSettings']);\n $router\n ->post(\n '/group/{group}/sidekick',\n [SidekickController::class, 'setSidekickSettings'],\n )\n ->middleware(['can:updateSidekickSettings,group'])\n ->name('api.sidekick_settings.update');\n $router\n ->post('/sidekick', [SidekickController::class, 'setSidekickSettings'])\n ->middleware(['permission:' . PermissionEnum::UPDATE_ALL_SIDEKICK_SETTINGS->value])\n ->name('api.sidekick_settings.update_all');\n },\n );\n\n $router->get('/deal-insights', [TeamDealInsightsSettingController::class, 'index']);\n $router->patch('/deal-insights', [TeamDealInsightsSettingController::class, 'update']);\n\n // CRM Layout Management\n $router->group(['prefix' => 'layouts'], static function (Router $router): void {\n $router->get(\n '/{type}',\n [Controllers\\API\\LayoutManagementController::class, 'list'],\n )->name('layouts.list');\n\n $router->put(\n '/{layout}',\n [Controllers\\API\\LayoutManagementController::class, 'update'],\n )->name('layouts.update');\n });\n\n // Users.\n $router->put('/users/{user}', [TeamMemberController::class, 'update'])\n ->middleware(['permission:' . PermissionEnum::MANAGE_USERS->value])\n ->name('api.users.update');\n $router->delete('/users/{user}', [TeamMemberController::class, 'deactivate'])\n ->middleware(['permission:' . PermissionEnum::MANAGE_USERS->value])\n ->name('api.users.deactivate');\n\n $router->group(\n [\n 'prefix' => 'vocabulary',\n 'middleware' => 'can:manage,' . Vocabulary::class,\n ],\n static function (Router $router): void {\n $router\n ->get('/', [VocabularyController::class, 'list'])\n ->name('api.vocabulary.index');\n $router\n ->post('/', [VocabularyController::class, 'update'])\n ->name('api.vocabulary.create');\n\n $router->group(['prefix' => '{vocabulary}'], static function (Router $router): void {\n $router\n ->put('/', [VocabularyController::class, 'update'])\n ->middleware('can:update,vocabulary')\n ->name('api.vocabulary.update');\n $router\n ->delete('/', [VocabularyController::class, 'delete'])\n ->middleware('can:delete,vocabulary')\n ->name('api.vocabulary.delete');\n });\n },\n );\n\n $router->group(['prefix' => 'ai-context'], static function (Router $router): void {\n $router->get('/', [TeamAiContextController::class, 'index'])\n ->name('api.ai_context.get');\n $router->post('/', [TeamAiContextController::class, 'store'])\n ->name('api.ai_context.store');\n });\n\n $router->group(['prefix' => 'ai-automation'], static function (Router $router): void {\n $router->post('/fields/test-prompt', [TeamAiAutomationController::class, 'testCrmAiPrompt'])\n ->name('api.automation.templates.fields.test-prompt');\n // List CRM fields per object type\n $router->get('/fields/{objectType}', [TeamAiAutomationController::class, 'fields'])\n ->name('api.automation.fields');\n\n // List DealStages fields per object type\n $router->get('/stages', [TeamAiAutomationController::class, 'stages'])\n ->name('api.automation.stages');\n // Create CRM AI template\n $router->post('/templates', [TeamAiAutomationController::class, 'createTemplate'])\n ->name('api.automation.templates.create');\n\n // Export CRM updates\n $router->post('/templates/export-crm-updates', [TeamAiAutomationController::class, 'exportTemplateCrmUpdates'])\n ->name('api.automation.templates.export-crm-updates');\n\n // Update CRM AI template\n $router->put('/templates/{crmTemplate}', [TeamAiAutomationController::class, 'updateTemplate'])\n ->name('api.automation.templates.update');\n // Delete CRM AI template\n $router->delete('/templates/{crmTemplate}', [TeamAiAutomationController::class, 'deleteTemplate'])\n ->name('api.automation.templates.delete');\n // List all CRM AI templates\n $router->get('/templates', [TeamAiAutomationController::class, 'templates'])\n ->name('api.automation.templates.list');\n // Create CRM AI template field\n $router->post('/templates/{crmTemplate}/fields', [TeamAiAutomationController::class, 'createField'])\n ->name('api.automation.templates.fields.create');\n // Update CRM AI template field\n $router->put('/templates/{crmTemplate}/fields/{crmTemplateField}', [TeamAiAutomationController::class, 'updateField'])\n ->name('api.automation.templates.fields.update');\n // Delete CRM AI template field\n $router->delete('/templates/{crmTemplate}/fields/{crmTemplateField}', [TeamAiAutomationController::class, 'deleteField'])\n ->name('api.automation.templates.fields.delete');\n });\n\n $router->group(['prefix' => 'ai-call-scoring'], static function (Router $router): void {\n // Create AI scorecard\n $router->post('/ai-scorecards', [Controllers\\API\\AiCallScoring\\AiScorecardController::class, 'createAiScorecard'])\n ->name('api.ai-call-scoring.ai-scorecards.create');\n // Update AI scorecard\n $router->put('/ai-scorecards/{aiScorecard}', [Controllers\\API\\AiCallScoring\\AiScorecardController::class, 'updateAiScorecard'])\n ->name('api.ai-call-scoring.ai-scorecards.update');\n // Delete AI scorecard\n $router->delete('/ai-scorecards/{aiScorecard}', [Controllers\\API\\AiCallScoring\\AiScorecardController::class, 'deleteAiScorecard'])\n ->name('api.ai-call-scoring.ai-scorecards.delete');\n // Test AI scorecard prompt\n $router->post(\n '/ai-scorecards/{aiScorecard}/test-prompt',\n [\n Controllers\\API\\AiCallScoring\\AiScorecardController::class,\n 'testAiScorecardPrompt',\n ]\n )\n ->name('api.ai-call-scoring.ai-scorecards.test-prompt');\n\n // Create AI Scorecard rule\n $router->post('/ai-scorecards/{aiScorecard}/ai-scorecard-rules', [Controllers\\API\\AiCallScoring\\AiScorecardRuleController::class, 'createRule'])\n ->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.create');\n // Update AI Scorecard rule\n $router->put('/ai-scorecards/{aiScorecard}/ai-scorecard-rules/{aiScorecardRule}', [Controllers\\API\\AiCallScoring\\AiScorecardRuleController::class, 'updateAiScorecardRule'])\n ->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.update');\n // Delete AI Scorecard rule\n $router->delete('/ai-scorecards/{aiScorecard}/ai-scorecard-rules/{aiScorecardRule}', [Controllers\\API\\AiCallScoring\\AiScorecardRuleController::class, 'deleteAiScorecardRule'])\n ->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.delete');\n });\n\n // Theme, topics, triggers\n $router->get('/themes', [ThemeController::class, 'list']);\n $router\n ->post('/themes', [ThemeController::class, 'updateTheme'])\n ->middleware('can:manage,' . PlaybackTheme::class)\n ->name('api.theme.create');\n\n $router->group(\n [\n 'prefix' => 'theme/{theme}',\n 'middleware' => 'can:update,theme',\n ],\n static function (Router $router): void {\n $router\n ->put('/', [ThemeController::class, 'updateTheme'])\n ->name('api.theme.update');\n $router\n ->delete('/', [ThemeController::class, 'deleteTheme'])\n ->middleware('can:delete,theme')\n ->name('api.theme.delete');\n\n $router\n ->post('/topics', [TopicController::class, 'updateTopic'])\n ->middleware('can:createTopic,theme')\n ->name('api.topic.create');\n\n $router->group(\n [\n 'prefix' => 'topic/{topic}',\n 'middleware' => 'can:update,topic',\n ],\n static function (Router $router): void {\n $router\n ->put('/', [TopicController::class, 'updateTopic'])\n ->name('api.topic.update');\n $router\n ->delete('/', [TopicController::class, 'deleteTopic'])\n ->middleware('can:delete,topic')\n ->name('api.topic.delete');\n\n $router\n ->post('/triggers', [TopicTriggerController::class, 'updateTrigger'])\n ->middleware('can:createTrigger,topic')\n ->name('api.topic_trigger.create');\n\n $router->group(\n [\n 'prefix' => 'trigger/{topicTrigger}',\n 'middleware' => 'can:update,topicTrigger',\n ],\n static function (Router $router): void {\n $router\n ->put('/', [TopicTriggerController::class, 'updateTrigger'])\n ->name('api.topic_trigger.update');\n $router\n ->delete('/', [TopicTriggerController::class, 'deleteTrigger'])\n ->middleware('can:delete,topicTrigger')\n ->name('api.topic_trigger.delete');\n },\n );\n },\n );\n },\n );\n\n $router->post('/themes/import', [Controllers\\API\\Themes\\ImportTopicTriggerController::class, 'importThemes']);\n $router->get('/themes/export', [Controllers\\API\\Themes\\ExportTopicTriggerController::class, 'exportThemes']);\n\n // Auto-scoring\n $router->group(['prefix' => '/scorecards'], static function (Router $router) {\n $router->get('/', [Controllers\\API\\Scorecards\\ScorecardController::class, 'list']);\n $router->post('/', [Controllers\\API\\Scorecards\\ScorecardController::class, 'create']);\n $router->delete('/{scorecard}', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'delete',\n ]);\n $router->post('/validate-name', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'validateNameExists',\n ]);\n\n $router->get('/enabled-scorecard', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'getEnabledScorecard',\n ]);\n\n $router->get('/affected-scorecards', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'getAffectedScorecards',\n ]);\n\n $router->group(['prefix' => '/{scorecard}'], static function (Router $router) {\n $router->put('/', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'update',\n ]);\n $router->delete('/', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'delete',\n ]);\n\n $router->post('/rules', [\n Controllers\\API\\Scorecards\\ScorecardRuleController::class,\n 'create',\n ]);\n\n $router->post('/rules/{scorecardRule}', [\n Controllers\\API\\Scorecards\\ScorecardRuleController::class,\n 'update',\n ]);\n\n $router->delete('/rules/{scorecardRule}', [\n Controllers\\API\\Scorecards\\ScorecardRuleController::class,\n 'delete',\n ]);\n\n $router->post('/rules/{scorecardRule}/update-order', [\n Controllers\\API\\Scorecards\\ScorecardRuleController::class,\n 'updateOrder',\n ]);\n });\n });\n\n // Coaching Playbook.\n Route::get('/playbooks', [PlaybookController::class, 'all']);\n Route::get('/playbooksTree', [PlaybookController::class, 'tree']);\n Route::put('/playbooks/{playbook}', [PlaybookController::class, 'update']);\n Route::post('/playbooks', [PlaybookController::class, 'store']);\n Route::delete('/playbooks/{playbook}', [PlaybookController::class, 'destroy']);\n\n Route::prefix('/playbooks/{playbook}')->group(static function () {\n // Playbook Categories.\n Route::get('/categories', [PlaybookCategoryController::class, 'all']);\n Route::put('/categories/sequence', [PlaybookCategoryController::class, 'sequence']); // Respect order.\n Route::put('/categories/{category}', [PlaybookCategoryController::class, 'update']);\n Route::post('/categories', [PlaybookCategoryController::class, 'store']);\n Route::post('/test-prompt', [PlaybookController::class, 'testAiActivityTypePrompt']);\n Route::post('/prompt-suggestion', [PlaybookController::class, 'getPromptSuggestion']);\n Route::delete('/categories/{category}', [PlaybookCategoryController::class, 'destroy']);\n\n Route::prefix('/categories/{category}')->group(static function () {\n // Coaching Sections\n Route::get('/coaching-section', [Controllers\\Settings\\Coaching\\SectionsController::class, 'all']);\n Route::put('/coaching-section/sequence', [Controllers\\Settings\\Coaching\\SectionsController::class, 'sequence']);\n Route::put('/coaching-section/{coachingSection}', [Controllers\\Settings\\Coaching\\SectionsController::class, 'update']);\n Route::post('/coaching-section', [Controllers\\Settings\\Coaching\\SectionsController::class, 'store']);\n Route::delete('/coaching-section/{coachingSection}', [Controllers\\Settings\\Coaching\\SectionsController::class, 'destroy']);\n\n Route::prefix('coaching-section/{coachingSection}')->group(static function () {\n // Coaching Section Criteria\n Route::get('/coaching-section-criterion', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'all']);\n Route::put('/coaching-section-criterion/sequence', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'sequence']);\n Route::put('/coaching-section-criterion/{coachingSectionCriterion}', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'update']);\n Route::post('/coaching-section-criterion', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'store']);\n Route::delete('/coaching-section-criterion/{coachingSectionCriterion}', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'destroy']);\n });\n });\n });\n },\n );\n\n // List all AI scorecards (accessible to all team members, no MANAGE_TEAM required)\n $router->get('/ai-call-scoring/ai-scorecards', [Controllers\\API\\AiCallScoring\\AiScorecardController::class, 'aiScorecards'])\n ->name('api.ai-call-scoring.ai-scorecards.list');\n\n $router->middleware(['permission:' . PermissionEnum::MANAGE_ORGANIZATION_SETTINGS->value])\n ->group(static function (Router $router): void {\n // Job Titles.\n $router->get('/job-titles', [JobTitleController::class, 'all']);\n $router->put('/job-titles/{job}', [JobTitleController::class, 'update']);\n $router->post('/job-titles', [JobTitleController::class, 'store']);\n $router->delete('/job-titles/{job}', [JobTitleController::class, 'destroy']);\n\n // Team Settings.\n $router->put('/', [TeamSettingsController::class, 'update']);\n $router->put('/notifications', [TeamSettingsController::class, 'updateNotifications']);\n $router->put('/team-conference', [TeamConferenceSettingsController::class, 'update']);\n $router->put('/team-coaching', [TeamCoachingSettingsController::class, 'update']);\n $router->put('/team-softphone', [TeamSoftphoneSettingsController::class, 'update']);\n $router->put('/owner', [Controllers\\Settings\\Teams\\OrganizationSettingsController::class, 'updateOwner']);\n\n $router->put('/team-recording', [TeamRecordingSettingsController::class, 'update'])\n ->middleware(['permission:' . PermissionEnum::MANAGE_RECORDING->value]);\n\n // Key Moments.\n $router->get('/moments/{moment}', [Controllers\\Settings\\MomentController::class, 'show']);\n $router->put('/moments/{moment}', [Controllers\\Settings\\MomentController::class, 'update']);\n $router->post('/moments', [Controllers\\Settings\\MomentController::class, 'store']);\n $router->put('/activity', [TeamActivityController::class, 'store']);\n\n // Team Domains.\n $router->get('/domains', [Controllers\\Settings\\Teams\\TeamDomainsController::class, 'all']);\n $router->post('/domains', [Controllers\\Settings\\Teams\\TeamDomainsController::class, 'create']);\n $router->delete('/domains/{teamDomain}', [Controllers\\Settings\\Teams\\TeamDomainsController::class, 'destroy']);\n });\n });\n });\n });\n\n // Integrations\n $router->group(['middleware' => 'permission:' . PermissionEnum::MANAGE_INTEGRATIONS->value], static function (Router $router): void {\n $router->post('/integrations', [IntegrationController::class, 'internal'])\n ->name('api.integrations.internal');\n $router->put('/integrations', [IntegrationController::class, 'toggleStatus'])\n ->name('api.integrations.toggle_status');\n $router->delete('/integrations/{provider}', [IntegrationController::class, 'delete'])\n ->name('api.integrations.delete');\n });\n\n $router->get('/integrations', [IntegrationController::class, 'all'])\n ->middleware('permission:' . PermissionEnum::READ_INTEGRATIONS->value)\n ->name('api.integrations.index');\n\n // Slack API for getting slack channels list\n $router->get('{notificationProvider}/channels', [Controllers\\NotificationProviderController::class, 'channels']);\n\n\n // Team actions. XXX: These all need moving out to their own controllers.\n $router->group(['prefix' => 'organizations'], static function (Router $router): void {\n $router->get('current', [TeamController::class, 'current']);\n\n $router->group(['prefix' => '{team}', 'middleware' => ['teamMember']], static function (Router $router): void {\n $router->get('/', [TeamController::class, 'show']);\n\n $router->get('/categories', [TeamController::class, 'categories']);\n $router->get('/stages', [TeamController::class, 'stages']);\n $router->get('/users', [OrganizationMembersController::class, 'index'])\n ->name('organization.members.index');\n $router\n ->get('/users/download', [OrganizationMembersController::class, 'download'])\n ->middleware('permission:' . PermissionEnum::MANAGE_USERS->value)\n ->name('organization.members.download');\n $router->get('/licensed-roles', [OrganizationLicensesController::class, 'index'])\n ->middleware('permission:' . PermissionEnum::MANAGE_BILLING->value)\n ->name('organization.licensed-roles.index');\n $router->get('/invitations', [TeamController::class, 'invitations']);\n $router->get('/groups', [TeamController::class, 'groups']);\n $router->delete('/groups/{group}', [TeamController::class, 'deleteGroup'])\n ->middleware(['permission:' . PermissionEnum::DELETE_TEAM->value])\n ->name('api.groups.delete');\n $router->get('/job-titles', [TeamController::class, 'jobTitles']);\n $router->get('/slugs', [TeamController::class, 'slugs']);\n $router->put('/api-token', [TeamController::class, 'generateApiToken'])\n ->middleware(['permission:' . PermissionEnum::MANAGE_ORGANIZATION_SETTINGS->value]);\n $router->get('/key-moments', [MomentController::class, 'all']);\n });\n });\n\n // Internal Kiosk. This whole section will be moved out to a separate file\n $router\n ->prefix('kiosk')\n ->middleware('can:kiosk,' . User::class)\n ->group(static function (Router $router): void {\n // Partner actions.\n $router->get('/partners', [PartnersController::class, 'index']);\n\n // User actions.\n $router->post('/users/search', [SearchController::class, 'performBasicSearch']);\n\n // Team actions.\n $router->prefix('organizations')->group(static function (Router $router): void {\n $router->get('/', [OrganizationsController::class, 'show']);\n $router->put('/{team}', [OrganizationController::class, 'edit'])\n ->name('kiosk.organizations.edit');\n $router->get('/{team}/users', [OrganizationMembersController::class, 'index'])\n ->name('kiosk.organization.members.index');\n $router->get('onboardable', [OnboardController::class, 'available']);\n $router->delete('/{team}', [OrganizationsController::class, 'deactivateAccounts']);\n });\n\n // Automated reports\n // api/v1/kiosk/automated-reports\n $router->prefix('automated-reports')->group(static function (Router $router): void {\n $router->get('/form-data', [AutomatedReportsController::class, 'getCreateForm']);\n $router->get('/form-data/{reportUuid}', [AutomatedReportsController::class, 'getEditForm']);\n $router->post('/filters', [AutomatedReportsController::class, 'getFilters']);\n $router->post('/', [AutomatedReportsController::class, 'create']);\n $router->put('/{reportUuid}', [AutomatedReportsController::class, 'update']);\n $router->patch('/{reportUuid}', [AutomatedReportsController::class, 'partialUpdate']);\n $router->get('/', [AutomatedReportsController::class, 'list']);\n $router->get('/{reportUuid}', [AutomatedReportsController::class, 'get']);\n $router->delete('/{reportUuid}', [AutomatedReportsController::class, 'delete']);\n $router->post('/activities-count', [AutomatedReportsController::class, 'getActivitiesCount']);\n $router->get('/{reportUuid}/reports-count', [AutomatedReportsController::class, 'getReportsCount']);\n });\n\n // Activity actions.\n $router->post('/activity/search', [SearchController::class, 'performActivitySearch']);\n $router->prefix('activity/{activity}')->group(static function (Router $router): void {\n $router->post('check-playable', [SearchController::class, 'performActivityCheckPlayable']);\n $router->post('reset-crm-log', [SearchController::class, 'performResetCrmLogActivity']);\n $router->get('diarize-via-transcript', [KioskActivityController::class, 'diarizeViaTranscript']);\n $router->post('diarize-via-transcript', [KioskActivityController::class, 'diarizeViaTranscript']);\n $router->get('media-pipeline', [MediaPipelineController::class, 'getPipes']);\n $router->post('media-pipeline', [MediaPipelineController::class, 'updatePipe']);\n $router->post('language', [KioskActivityController::class, 'updateLanguage']);\n $router->post('trim', [KioskActivityController::class, 'trimActivity']);\n $router->get('troubleshoot', [KioskActivityController::class, 'troubleshootActivity']);\n $router->get('transcription', [KioskActivityController::class, 'getTranscriptions']);\n $router->post('speakers', [KioskActivityController::class, 'addSpeakers']);\n $router->post('crm-fields-fill', [KioskActivityController::class, 'crmFieldsFill']);\n $router->post('summary-highlights', [KioskActivityController::class, 'summaryHighlights']);\n });\n });\n});\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->group(['prefix' => 'events'], static function (Router $router): void {\n $router->post('authenticate', [Controllers\\PusherController::class, 'auth'])\n ->name(Routes::WEBHOOK_PUSHER_AUTH);\n });\n});\n\n$router->group(['middleware' => ['api']], static function (Router $router): void {\n $router->get('/extensions/auth', [ExtensionController::class, 'authenticate']);\n $router->get('/call-token/{team}/{participant?}', [ClientTokenController::class, 'generateToken']);\n});\n\n$router->group(['prefix' => 'user'], static function (Router $router): void {\n $router->get('chrome-extension-authentication', [ExtensionController::class, 'authenticate']);\n});\n\n$router->group(['middleware' => ['auth:api'], 'prefix' => 'sms'], static function (Router $router): void {\n $router->get('/{phoneNumber}', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'messages']);\n $router->get('/', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'messagesList']);\n $router->post('/', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'send']);\n $router->delete('/{activity}', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'redact']);\n $router->put('/{activity}', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'resend']);\n});\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/users/current', [UserController::class, 'current']);\n\n $router->get('/users/slug/{slug?}', [UserController::class, 'validateSlug']);\n\n // Profile Contact Information.\n $router->put(\n '/users/{user}/settings/profile',\n [Controllers\\Settings\\Profile\\ContactInformationController::class, 'update'],\n );\n\n $router->get('/users/{user}/email-sync-settings', [EmailSyncController::class, 'index']);\n $router->put('/users/{user}/email-sync-settings', [EmailSyncController::class, 'update']);\n\n // SMS Settings.\n $router->put('/users/{user}/settings/sms', [Controllers\\Settings\\Profile\\SmsController::class, 'update']);\n\n $router->get('/settings/timezones', [Controllers\\API\\Settings\\TimeZoneController::class, 'index'])\n ->name('settings.timezones.index');\n\n $router->put('/settings/user/deal-insights', [Controllers\\Settings\\Users\\UserSettingsController::class, 'update']);\n});\n\n$router->group(['prefix' => 'page', 'middleware' => ['api', 'auth:api']], static function () use ($router): void {\n $router->get('/playback/{activity}', [PlaybackController::class, 'show'])\n ->name('api.playback');\n $router->get('/on-demand', [OnDemandController::class, 'show'])\n ->name('api.activity.search');\n});\n\n$router->group(['prefix' => 'partners', 'middleware' => 'auth:partner-api'], static function () use ($router): void {\n $router->get('/', [PartnerController::class, 'me']);\n\n $router->group(['prefix' => 'organizations'], static function () use ($router): void {\n $router->get('/{team}', [PartnerController::class, 'fetchOrganization']);\n $router->post('/', [PartnerController::class, 'createOrganization']);\n });\n\n $router->group(['prefix' => 'groups'], static function () use ($router): void {\n $router->get('/{group}', [PartnerController::class, 'fetchGroup']);\n $router->post('/', [PartnerController::class, 'createGroup']);\n });\n\n $router->group(['prefix' => 'users'], static function () use ($router): void {\n $router->get('/{user}', [PartnerController::class, 'fetchUser']);\n $router->post('/', [PartnerController::class, 'createUser']);\n $router->delete('/{user}', [PartnerController::class, 'deactivateUser']);\n });\n\n $router->group(['prefix' => 'activities'], static function () use ($router): void {\n $router->get('/{activity}', [PartnerController::class, 'fetchActivity']);\n $router->get('/', [PartnerController::class, 'searchActivity']);\n });\n});\n\n$router->group(['prefix' => 'activity', 'middleware' => 'api'], static function () use ($router): void {\n // User only.\n $router->group(['middleware' => ['auth:api']], static function () use ($router): void {\n // Bulk delete\n $router->delete('/', [ActivityController::class, 'delete']);\n\n // Search.\n $router->get('/search', [ActivityController::class, 'search']);\n\n // All comments.\n $router->get('/comments', [ActivityController::class, 'fetchComments']);\n\n // Transcription AI\n $router->get('/{activity}/action-items', [Controllers\\API\\ActionItemsController::class, 'index']);\n $router->get('/{activity}/ai-call-scoring', [Controllers\\API\\AiCallScoring\\AiCallScoringController::class, 'index']);\n\n $router->get('/saved-search', [ActivityController::class, 'listActivitySearch'])->name('api.saved_search.index');\n $router->get('/saved-search/{search}', [ActivityController::class, 'fetchActivitySearch'])->name('api.saved_search.show');\n $router->post('/saved-search', [ActivityController::class, 'createActivitySearch'])->name('api.saved_search.create');\n $router->put('/saved-search/{search}', [ActivityController::class, 'updateActivitySearch'])->name('api.saved_search.update');\n $router->delete('/saved-search/{search}', [ActivityController::class, 'deleteActivitySearch'])->name('api.saved_search.delete');\n\n $router->post('/saved-search/{search}/nudges', [NudgeController::class, 'createAction'])->name('api.nudges.create');\n $router->put('/saved-search/{search}/nudges/{nudge}', [NudgeController::class, 'updateAction'])->name('api.nudges.update');\n $router->delete('/saved-search/{search}/nudges/{nudge}', [NudgeController::class, 'deleteAction'])->name('api.nudges.delete');\n\n // Live (coaching).\n $router->get('/live', [ActivityController::class, 'live']);\n $router->get('/{activity}/cloudfront-s3-media-keys', [ActivityController::class, 'fetchCloudFrontS3MediaKeys']);\n\n $router->post('/softphone', [SoftphoneController::class, 'create']);\n $router->put('/softphone', [SoftphoneController::class, 'createCoachParticipant']);\n $router->post('/softphone/dial', [SoftphoneController::class, 'dial']);\n $router->get('/softphone/{activity}', [SoftphoneController::class, 'fetch']);\n $router->delete('/softphone/{activity}', [SoftphoneController::class, 'endCall']);\n\n $router->post('softphone/{activity}/message', [SoftphoneController::class, 'message']);\n });\n\n // Activity actions.\n $router->group(['prefix' => '{activity}', 'middleware' => ['auth:api']], static function (Router $router): void {\n // User only.\n $router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n // Messages endpoint.\n $router->post('/message', [MessageController::class, 'message']);\n\n // Organizer actions.\n $router->put('/', [ActivityController::class, 'update']);\n $router->get('/', [ActivityController::class, 'show']);\n $router->delete('/', [ActivityController::class, 'destroy']);\n\n $router->post('/recording', [ActivityController::class, 'createRecording']);\n $router->put('/recording', [ActivityController::class, 'updateRecording']);\n $router->delete('/recording', [ActivityController::class, 'stopRecording']);\n\n $router->post('/summarize', [ActivityController::class, 'summarize']);\n\n // Sales Activity Playback action.\n $router->put('/favorite', [ActivityController::class, 'favorite']);\n $router->delete('/favorite', [ActivityController::class, 'unfavorite']);\n\n $router->put('/private', [ActivityController::class, 'markAsPrivate']);\n $router->delete('/private', [ActivityController::class, 'markAsPublic']);\n\n $router->put('/notification', [ActivityController::class, 'notify']);\n $router->delete('/notification/{notification}', [ActivityController::class, 'unnotify']);\n\n // Activity comments\n $router->put('/comment/{comment}', [ActivityController::class, 'updateComment']);\n $router->post('/comment/{comment}', [ActivityController::class, 'replyComment']);\n $router->post('/comment', [ActivityController::class, 'comment']);\n $router->delete('/comment/{comment}', [ActivityController::class, 'deleteComment']);\n $router->put('/comment/{comment}/visibility', [ActivityController::class, 'updateCommentVisibility']);\n\n $router->get('/coaching-sections', [ActivityController::class, 'coachingSections']);\n\n $router->put('/coach', [ActivityController::class, 'putCoachingFeedback']);\n $router->delete('/coach/{coachingFeedback}', [ActivityController::class, 'deleteCoachingFeedback']);\n\n $router->post('/coach-request', [ActivityController::class, 'coachRequest']);\n $router->post('/share', [ActivityController::class, 'share']);\n\n $router->post('/playlists', [ActivityController::class, 'addToPlaylist'])\n ->name('playlists.add.activity');\n\n $router->post('/key-moment', [MomentController::class, 'store']);\n\n $router->put('/play', [ActivityController::class, 'play']);\n\n $router->get('/stats', [ActivityController::class, 'stats']);\n\n $router->get('/topic-triggers', [ActivityController::class, 'fetchActivityTopicTriggers']);\n\n $router->post('/topic-triggers', [ActivityController::class, 'createActivityTopicTriggers']);\n\n $router->get('/auto-score', [Controllers\\API\\Scorecards\\AutoScoreController::class, 'getAutoScore']);\n $router->post('/auto-score', [Controllers\\API\\Scorecards\\AutoScoreController::class, 'updateAutoScore']);\n\n // Get Download link for an activity\n $router->get('/download', [Controllers\\PlaybackController::class, 'getDownloadUrl'])->name('getDownloadUrl');\n\n $router->post('/note', [ActivityController::class, 'note']);\n\n $router->post('/export', [ExportController::class, 'share'])\n ->middleware(['throttle:activity-export']);\n\n $router->post('/shareable-link', [ExportController::class, 'getShareableLink'])\n ->middleware(['throttle:activity-export-shareable-link']);\n\n $router->group(['prefix' => 'transcription'], static function (Router $router): void {\n $router->get('/', [TranscriptionController::class, 'getTranscriptionByActivity']);\n $router->get('/search', [TranscriptionController::class, 'searchAction']);\n $router->get('/download', [TranscriptionController::class, 'downloadTranscriptionByActivity'])\n ->middleware(['throttle:transcription-download']);\n $router->put('/attribution-flip/{participantA}/{participantB}', [Controllers\\API\\TranscriptionController::class, 'speakerAttributionFlip']);\n $router->put('/attribution-change/{participant}', [Controllers\\API\\TranscriptionController::class, 'speakerAttributionChange']);\n $router->get('/translation', [TranslationController::class, 'getTranslation']);\n });\n });\n });\n});\n\n$router->group(['middleware' => ['auth:api']], static function () use ($router) {\n $router->put('/subscription/{morphType}', [SubscriptionController::class, 'subscribe']);\n $router->delete('/subscription/{morphType}', [SubscriptionController::class, 'unsubscribe']);\n});\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/playlists', [PlaylistController::class, 'all'])->name('api.playlists.all');\n $router->get('/playlists/user', [PlaylistController::class, 'userPlaylists'])\n ->name('api.playlists.userPlaylists');\n $router->post('/playlists', [PlaylistController::class, 'store'])->name('api.playlists.store');\n\n $router->post('/playlists/{playlist}/share', [PlaylistController::class, 'share'])\n ->name('api.playlist.create.share');\n $router->get('/playlists/{playlist}/activities', [PlaylistController::class, 'activities'])\n ->name('api.playlist.activities');\n $router->delete('/playlists/{playlist}/shares/{playlistShare}', [PlaylistController::class, 'unshare'])\n ->name('api.playlist.unshare');\n $router->get('/playlists/{playlist}/shares', [PlaylistController::class, 'shares'])\n ->name('api.playlist.get.shares');\n $router->post('/playlists/{playlist}/lock', [PlaylistController::class, 'lock'])->name('api.playlist.lock');\n $router->post('/playlists/{playlist}/unlock', [PlaylistController::class, 'unlock'])\n ->name('api.playlist.unlock');\n $router->get(\n '/playlists/{playlist}/available-playlists',\n [PlaylistController::class, 'availablePlaylistsToMoveTo'],\n )->name('api.playlist.available');\n $router->put('/playlists/{playlist}', [PlaylistController::class, 'update'])->name('api.playlist.update');\n $router->delete('/playlists/{playlist}', [PlaylistController::class, 'destroy'])\n ->name('api.playlist.destroy');\n $router->put(\n '/playlists/{playlist}/tracks/{playlistActivity}',\n [PlaylistController::class, 'updatePlaylistTrack'],\n )->name('api.playlist.updatePlaylistTrack');\n $router->put(\n '/playlists/{playlist}/tracks/{playlistActivity}/move',\n [PlaylistController::class, 'moveToPlaylist'],\n )->name('api.playlist.moveToPlaylist');\n $router->delete(\n '/playlists/{playlist}/tracks/{playlistActivity}',\n [PlaylistController::class, 'removeFromPlaylist'],\n )->name('api.playlist.removeFromPlaylist');\n});\n\n$router->group(\n ['prefix' => '/opportunity/{opportunity}', 'middleware' => ['api']],\n static function (Router $router): void {\n // Opportunity comments\n $router->group(['prefix' => '/comment', 'middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/', [CommentsController::class, 'fetchComments']);\n $router->post('/', [CommentsController::class, 'comment']);\n\n $router->group(['prefix' => '{comment}'], static function (Router $router): void {\n $router->put('/', [CommentsController::class, 'updateComment']);\n $router->post('/', [CommentsController::class, 'replyComment']);\n $router->delete('/', [CommentsController::class, 'deleteComment']);\n $router->put('/visibility', [CommentsController::class, 'updateCommentVisibility']);\n });\n });\n },\n);\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/playlist/{activity}.m3u8', [Controllers\\API\\PlaybackController::class, 'playlist']);\n $router->get('/media/{track}.m3u8', [Controllers\\API\\PlaybackController::class, 'media']);\n});\n\n$router->group(['middleware' => ['api']], static function (Router $router): void {\n // SSO email query.\n $router->get('/auth/sso/login', [Controllers\\API\\SsoController::class, 'ssoLogin'])->name('ssoLogin');\n});\n\n$router->get('/mobile-settings', [MobileSettingsController::class, 'getAll']);\n\n$router->put('/mobile-settings', [MobileSettingsController::class, 'updateSettings'])\n ->middleware(['auth:api', 'can:kiosk,' . User::class])\n ->name('api.kiosk.mobile_settings.update');\n\n// Ask Jiminny on deal level\n$router->get('deals/{opportunity}/ask-jiminny', [Controllers\\API\\DealLevelPromptsController::class, 'index'])\n ->middleware(['api', 'auth:api'])\n ->name('api.deals.ask-jiminny');\n\n$router->get('get-access-token/{provider?}', [SocialController::class, 'getAccessToken'])\n ->name('api.get_access_token')\n ->whereIn('provider', [SocialAccount::PROVIDER_HUBSPOT]);\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->post('single-claim-token/{provider?}', [SocialController::class, 'getSingleUseClaim'])\n ->name('api.singe-claim-token');\n});\n\n$router->post('deauthorize-zoom-app', [SocialController::class, 'deauthorizeZoomApp'])\n ->name('api.deauthorize-zoom-app.recall-ai');\n\n$router->put('/conferences/{activity}/consent', [ConferencesOptInOutController::class, 'storeConsent'])\n ->middleware(['throttle:conference-consent'])\n ->name('api.conferences.store-consent');","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"bounds":{"left":0.41289893,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"bounds":{"left":0.42154256,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"bounds":{"left":0.4325133,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"bounds":{"left":0.44115692,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"bounds":{"left":0.44980052,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"bounds":{"left":0.46077126,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"bounds":{"left":0.47174203,"top":0.09896249,"width":0.024268618,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"bounds":{"left":0.49833778,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"bounds":{"left":0.5093085,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7237367,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-6894566648403368257
|
2696331441576594635
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
layout
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
2/6
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Built-in Preview
Chrome
Firefox
Safari
Sync Changes
Hide This Notification
Code changed:
Hide
11
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
/**
* API routes.
*
* @see \Jiminny\Providers\RouteServiceProvider
*
* @var Router $router
*/
use Illuminate\Routing\Router;
use Illuminate\Support\Collection;
use Jiminny\Component\DealInsights\Forecast\Forecast;
use Jiminny\Component\Router\Routes;
use Jiminny\Contracts\Acl\PermissionEnum;
use Jiminny\Http\Controllers;
use Jiminny\Http\Controllers\API\ActivityController;
use Jiminny\Http\Controllers\API\AiCrmNotesController;
use Jiminny\Http\Controllers\API\ClientTokenController;
use Jiminny\Http\Controllers\API\CrmController;
use Jiminny\Http\Controllers\API\TeamInsights\TeamInsightsAiCallScoringController;
use Jiminny\Http\Controllers\ConferencesOptInOutController;
use Jiminny\Http\Controllers\API\DealRiskController;
use Jiminny\Http\Controllers\API\InstantMeetingController;
use Jiminny\Http\Controllers\API\LanguageController;
use Jiminny\Http\Controllers\API\LiveFeedController;
use Jiminny\Http\Controllers\API\MeetingsController;
use Jiminny\Http\Controllers\API\MessageController;
use Jiminny\Http\Controllers\API\MetadataController;
use Jiminny\Http\Controllers\API\MobileSettingsController;
use Jiminny\Http\Controllers\API\MomentController;
use Jiminny\Http\Controllers\API\NudgeController;
use Jiminny\Http\Controllers\API\NumberAllocatorController;
use Jiminny\Http\Controllers\API\Opportunity\CommentsController;
use Jiminny\Http\Controllers\API\OrganizationLicensesController;
use Jiminny\Http\Controllers\API\OrganizationMembersController;
use Jiminny\Http\Controllers\API\OrganizationRetentionPolicyController;
use Jiminny\Http\Controllers\API\OrganizationRolesController;
use Jiminny\Http\Controllers\API\OrganizationSyncController;
use Jiminny\Http\Controllers\API\Page\OnDemandController;
use Jiminny\Http\Controllers\API\Page\PlaybackController;
use Jiminny\Http\Controllers\API\PartnerController;
use Jiminny\Http\Controllers\API\PhoneNumberController;
use Jiminny\Http\Controllers\API\PlaylistController;
use Jiminny\Http\Controllers\API\Settings\EmailSyncController;
use Jiminny\Http\Controllers\API\SidekickController;
use Jiminny\Http\Controllers\API\SoftphoneController;
use Jiminny\Http\Controllers\API\SubscriptionController;
use Jiminny\Http\Controllers\API\TeamAiAutomationController;
use Jiminny\Http\Controllers\API\TeamAiContextController;
use Jiminny\Http\Controllers\API\TeamController;
use Jiminny\Http\Controllers\API\TeamInsights\ActivityStatsController;
use Jiminny\Http\Controllers\API\TeamInsights\CoachingFeedbacksController;
use Jiminny\Http\Controllers\API\TeamInsights\DashboardController;
use Jiminny\Http\Controllers\API\TeamInsights\EngagementController;
use Jiminny\Http\Controllers\API\TeamInsights\TeamInsightsAutomatedCallScoresController;
use Jiminny\Http\Controllers\API\TeamInsights\ThemeTopicsController;
use Jiminny\Http\Controllers\API\TeamInsights\TopicsInDealsController;
use Jiminny\Http\Controllers\API\TeamInsightsController;
use Jiminny\Http\Controllers\API\Themes\ThemeController;
use Jiminny\Http\Controllers\API\Themes\TopicController;
use Jiminny\Http\Controllers\API\Themes\TopicTriggerController;
use Jiminny\Http\Controllers\API\TranscriptionController;
use Jiminny\Http\Controllers\API\TranslationController;
use Jiminny\Http\Controllers\API\UserAutomatedReports\UserAutomatedReportsController;
use Jiminny\Http\Controllers\API\UserController;
use Jiminny\Http\Controllers\API\VocabularyController;
use Jiminny\Http\Controllers\Auth\ExtensionController;
use Jiminny\Http\Controllers\Auth\SocialController;
use Jiminny\Http\Controllers\ExportController;
use Jiminny\Http\Controllers\Kiosk\ActivityController as KioskActivityController;
use Jiminny\Http\Controllers\Kiosk\AutomatedReportsController;
use Jiminny\Http\Controllers\Kiosk\MediaPipelineController;
use Jiminny\Http\Controllers\Kiosk\OrganizationsController;
use Jiminny\Http\Controllers\Kiosk\PartnersController;
use Jiminny\Http\Controllers\Kiosk\SearchController;
use Jiminny\Http\Controllers\Kiosk\Teams\OnboardController;
use Jiminny\Http\Controllers\NotificationController;
use Jiminny\Http\Controllers\Settings\GroupController;
use Jiminny\Http\Controllers\Settings\JobTitleController;
use Jiminny\Http\Controllers\Settings\PlaybookCategoryController;
use Jiminny\Http\Controllers\Settings\PlaybookController;
use Jiminny\Http\Controllers\Settings\Teams\IntegrationController;
use Jiminny\Http\Controllers\Settings\Teams\InvitationController;
use Jiminny\Http\Controllers\Settings\Teams\TeamActivityController;
use Jiminny\Http\Controllers\Settings\Teams\TeamCoachingSettingsController;
use Jiminny\Http\Controllers\Settings\Teams\TeamConferenceSettingsController;
use Jiminny\Http\Controllers\Settings\Teams\TeamController as OrganizationController;
use Jiminny\Http\Controllers\Settings\Teams\TeamDealInsightsSettingController;
use Jiminny\Http\Controllers\Settings\Teams\TeamMemberController;
use Jiminny\Http\Controllers\Settings\Teams\TeamPhotoController;
use Jiminny\Http\Controllers\Settings\Teams\TeamRecordingSettingsController;
use Jiminny\Http\Controllers\Settings\Teams\TeamSettingsController;
use Jiminny\Http\Controllers\Settings\Teams\TeamSoftphoneSettingsController;
use Jiminny\Http\Controllers\TeamSetupController;
use Jiminny\Models;
use Jiminny\Models\PlaybackTheme;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\User;
use Jiminny\Models\Vocabulary;
use Jiminny\Repositories;
use Jiminny\Mcp\Servers\JiminnyServer;
use Laravel\Mcp\Facades\Mcp;
// mcp.audit MUST stay outermost so its $next($request) call wraps the auth
// and tier guards. Otherwise 401 (auth:api) and 403 (mcp.tier) rejections
// short-circuit before McpAuditMiddleware::handle ever runs and we lose
// audit rows for exactly the requests the security log most needs to capture.
// McpAuditMiddleware::writeAuditRow null-checks $request->user(), so writing
// pre-auth is safe.
Mcp::web('/mcp', JiminnyServer::class)
->middleware(['mcp.audit', 'auth:api', 'mcp.tier']);
$router->group(['middleware' => ['auth:api']], static function (Router $router): void {
$router->get('/metadata/extension-app', [MetadataController::class, 'extension']);
$router->get('/', [NumberAllocatorController::class, 'generate']);
$router->delete('/key-moment/{activityMoment}', [MomentController::class, 'destroy']);
$router->post('/instant-meeting/start', [InstantMeetingController::class, 'postRequestBotAtUrl'])
->middleware(['permission:' . PermissionEnum::RECORD_MEETING->value])
->name('instant-meeting.start');
// Meeting creation endpoint for Outlook add-in
$router->post('/meetings', [MeetingsController::class, 'create'])
->middleware(['permission:' . PermissionEnum::RECORD_MEETING->value])
->name('meetings.create');
// Number provisioning and search.
$router->get('/phone-numbers', [NumberAllocatorController::class, 'generate']);
$router->get('/phone-numbers/{number}', [PhoneNumberController::class, 'number']);
$router->group(['prefix' => 'deal-insights'], static function (Router $router): void {
$router->get('/forecast', [
Controllers\API\DealInsights\DealsController::class,
'getForecast',
])->defaults('period', Forecast::PERIOD_QUARTER);
$router->get('/deals/{stage?}', [
Controllers\API\DealInsights\DealsController::class,
'list',
])->defaults('stage', \Jiminny\Component\DealInsights\CriteriaInterface::STAGE_ALL);
$router->get('/details/details-daily/{opportunityId}/{date}', [
Controllers\API\DealInsights\DealsController::class,
'detailsDaily',
]);
$router->put('/deals/{opportunity}/edit-fields', [
Controllers\API\DealInsights\DealsController::class,
'updateFields',
]);
$router->get('/externalId/{dealId}', [
Controllers\API\DealInsights\DealsController::class,
'externalDealId',
]);
$router->put('/dealRisk/{dealRisk}', [DealRiskController::class, 'toggleActivity']);
});
$router->get('/team-insights/users', [TeamInsightsController::class, 'fetchUsers'])
->name('team_insights.users');
$router->get('/team-insights/dashboard', [DashboardController::class, 'fetch'])
->name('team_insights.dashboard');
// Team Insights - Coaching Feedbacks
$router->get('/team-insights/coaching-feedbacks-over-time', [CoachingFeedbacksController::class, 'fetch'])
->name('team_insights.coaching_feedbacks_over_time');
$router
->get('/team-insights/coaching-feedbacks-over-time/download', [CoachingFeedbacksController::class, 'download'])
->name('team_insights.coaching_feedbacks_over_time.download');
$router->get(
'/team-insights/coaching-feedbacks-over-time/drill-down',
[CoachingFeedbacksController::class, 'drillDown'],
)->name('team_insights.coaching_feedbacks_over_time.drill_down');
// Team Insights - Automated Call Scores
$router->get(
'/team-insights/automated-call-scores-over-time',
[TeamInsightsAutomatedCallScoresController::class, 'index'],
)->name('team_insights.automated_call_scores_over_time.index');
$router->get(
'/team-insights/automated-call-scores-over-time/drill-down',
[TeamInsightsAutomatedCallScoresController::class, 'show'],
)->name('team_insights.automated_call_scores_over_time.show');
// Team Insights - AI Call Scoring
$router->get(
'/team-insights/ai-call-scoring-over-time',
[TeamInsightsAiCallScoringController::class, 'index'],
)->name('team_insights.ai_call_scoring_over_time.index');
$router->get(
'/team-insights/ai-call-scoring-over-time/drill-down',
[TeamInsightsAiCallScoringController::class, 'show'],
)->name('team_insights.ai_call_scoring_over_time.show');
$router->get('/team-insights/engagement', [ActivityStatsController::class, 'fetch'])
->name('team_insights.engagement');
$router->get('/team-insights/engagement/drill-down/{engagementType}', [ActivityStatsController::class, 'drillDown'])
->name('team_insights.engagement.drill_down');
$router->get('/team-insights/topics', [ThemeTopicsController::class, 'getTopics'])
->name('team_insights.topics.index');
$router->get('/team-insights/topics/{topic}', [ThemeTopicsController::class, 'fetch'])
->name('team_insights.topics.show');
$router->get('/team-insights/topics/{topic}/drill-down', [ThemeTopicsController::class, 'drillDown'])
->name('team_insights.topics.drill_down');
$router->group(['prefix' => 'team-insights'], static function (Router $router): void {
$router->group(['prefix' => 'conversations'], static function (Router $router): void {
$router->get('/', [
Controllers\API\TeamInsights\ConversationsController::class,
'fetch',
]);
$router->group(['prefix' => 'drill-down'], static function (Router $router): void {
$router
->get('/{activityChannel}/{drillDownType}', [
Controllers\API\TeamInsights\ConversationsController::class,
'drillDown',
])
->where(
'activityChannel',
Collection::make(Models\Activity::CHANNELS)->join('|'),
)
->where(
'drillDownType',
Collection::make(Repositories\TeamInsightsRepository::CONVERSATION_DRILLDOWNS)
->join('|'),
);
});
});
$router->group(['prefix' => 'coaching'], static function (Router $router): void {
$router->get('/', [EngagementController::class, 'fetch']);
$router->group(['prefix' => 'drill-down'], static function (Router $router): void {
$router
->get('/{coachingType}/{drillDownType?}', [EngagementController::class, 'drillDown'])
->where(
'coachingType',
Collection::make(EngagementController::COACHING_TYPES)->join('|'),
)
->where(
'drillDownType',
Collection::make(EngagementController::COACHING_DRILLDOWNS)->join('|'),
);
});
});
});
$router->get('/topics-in-deals', [TopicsInDealsController::class, 'topics'])
->name('topics_in_deals.topics');
$router->get('/topics-in-deals/topic-triggers', [TopicsInDealsController::class, 'topicTriggers'])
->name('topics_in_deals.topic_triggers');
$router->get('/compare-topics-in-deals', [TopicsInDealsController::class, 'comparison'])
->name('topics_in_deals.comparison');
// CRM actions.
$router->group(['prefix' => 'crm'], static function (Router $router): void {
$router->get('/search', [CrmController::class, 'search']);
$router->get('/opportunity', [CrmController::class, 'opportunities']);
$router->get('/customers', [CrmController::class, 'customers']);
$router->get('/accounts', [CrmController::class, 'accounts']);
$router->get('/contacts', [CrmController::class, 'contacts']);
$router->get('/leads', [CrmController::class, 'leads']);
$router->get('/tasks', [CrmController::class, 'activities']);
$router->get('/layouts', [CrmController::class, 'layouts']);
});
// AI CRM notes.
$router->group(['prefix' => 'ai-crm-notes'], static function (Router $router): void {
$router->get('/activity/{activity}', [AiCrmNotesController::class, 'getByActivity']);
$router->post('/activity/{activity}/log-to-crm', [AiCrmNotesController::class, 'logToCrmByActivity']);
$router->post('/activity/{activity}/discard', [AiCrmNotesController::class, 'discardByActivity']);
$router->get('/deal/{opportunity}', [AiCrmNotesController::class, 'getByOpportunity']);
$router->post('/deal/{opportunity}/log-to-crm', [AiCrmNotesController::class, 'logToCrmByOpportunity']);
$router->post('/deal/{opportunity}/discard', [AiCrmNotesController::class, 'discardByOpportunity']);
});
// Automated Reports
$router->post('/automated-reports/interest', [UserAutomatedReportsController::class, 'trackInterest']);
$router->group(
[
'prefix' => 'automated-reports',
'middleware' => 'can:canAccessAiReports,' . User::class,
],
static function (Router $router): void {
$router->get('/', [UserAutomatedReportsController::class, 'list']);
$router->delete('/{uuid}', [UserAutomatedReportsController::class, 'delete']);
}
);
// Setup New Team / Trial
$router->get('/features', [TeamSetupController::class, 'features']);
$router->get('/tiers', [TeamSetupController::class, 'tiers']);
$router->get('/calendars', [TeamSetupController::class, 'calendars']);
$router->get('/crm-services', [TeamSetupController::class, 'crmServices']);
$router->get('/connect-providers', [TeamSetupController::class, 'connectProviders']);
$router->get('/integration-app-token', [TeamSetupController::class, 'integrationAppToken']);
$router->post('/integration-app-connect', [TeamSetupController::class, 'integrationAppConnect']);
// Notifications
$router->get('/notifications/recent', [NotificationController::class, 'notifications']);
$router->put('/notifications/read', [NotificationController::class, 'markAsRead']);
$router->put('/notifications/read-multiple', [NotificationController::class, 'markMultipleAsRead']);
$router->put('/notifications/read-all', [NotificationController::class, 'markAllAsRead']);
// Live feed
$router->get('/live-feed', [LiveFeedController::class, 'liveFeedItems']);
// Languages
$router->get('/languages', [LanguageController::class, 'list']);
// The whole settings section will be moved out in a separate file
$router->group(['prefix' => '/settings'], static function (Router $router): void {
$router->group(['prefix' => '/organizations'], static function (Router $router): void {
$router
->middleware(['can:kiosk,' . User::class])
->post('/', [OrganizationController::class, 'store'])
->name('kiosk.organizations.store');
$router->group(['prefix' => '{team}', 'middleware' => ['teamMember']], static function (Router $router) {
// Sync fields and team metadata
$router->post('/fields/sync', [OrganizationSyncController::class, 'index'])
->name('api.sync.fields');
// Conference Preferences.
$router->post('/bot-avatar', [TeamPhotoController::class, 'updateBotAvatar'])
->name('update.bot.avatar');
// Roles.
$router->get('/roles', [OrganizationRolesController::class, 'index'])
->name('api.roles.index');
$router->group(
['middleware' => 'permission:' . PermissionEnum::MANAGE_RETENTION_POLICY->value],
static function (Router $router): void {
$router->get('/retention-policy', [OrganizationRetentionPolicyController::class, 'index'])
->name('api.retention_policy.index');
$router->post('/retention-policy', [OrganizationRetentionPolicyController::class, 'store'])
->name('api.retention_policy.update');
}
);
$router->group(
['middleware' => 'permission:' . PermissionEnum::MANAGE_USERS->value],
static function (Router $router): void {
// Invitations.
$router->get('/invitations', [InvitationController::class, 'index'])
->name('api.invitations.index');
$router->post('/invitations/{invitation}', [InvitationController::class, 'resend'])
->name('api.invitations.resend');
$router->delete('/invitations/{invitation}', [InvitationController::class, 'destroy'])
->name('api.invitations.delete');
$router->post('/invitations', [InvitationController::class, 'store'])
->name('api.invitations.store');
},
);
$router->group(
['middleware' => 'permission:' . PermissionEnum::MANAGE_TEAM->value],
static function (Router $router): void {
// Groups.
$router->post('/groups', [GroupController::class, 'store']);
$router->get('/groups/{group}', [GroupController::class, 'show']);
$router->put('/groups/{group}', [GroupController::class, 'update']);
$router->put('/group/{group}/scope', [GroupController::class, 'updateGroupScope']);
$router->post('/group/{group}/dealRisks', [DealRiskController::class, 'updateSettings']);
// Sidekick settings
$router->group(
['middleware' => 'permission:' . PermissionEnum::MANAGE_SIDEKICK->value],
static function (Router $router): void {
$router->get('/sidekick', [SidekickController::class, 'getSidekickSettings']);
$router
->post(
'/group/{group}/sidekick',
[SidekickController::class, 'setSidekickSettings'],
)
->middleware(['can:updateSidekickSettings,group'])
->name('api.sidekick_settings.update');
$router
->post('/sidekick', [SidekickController::class, 'setSidekickSettings'])
->middleware(['permission:' . PermissionEnum::UPDATE_ALL_SIDEKICK_SETTINGS->value])
->name('api.sidekick_settings.update_all');
},
);
$router->get('/deal-insights', [TeamDealInsightsSettingController::class, 'index']);
$router->patch('/deal-insights', [TeamDealInsightsSettingController::class, 'update']);
// CRM Layout Management
$router->group(['prefix' => 'layouts'], static function (Router $router): void {
$router->get(
'/{type}',
[Controllers\API\LayoutManagementController::class, 'list'],
)->name('layouts.list');
$router->put(
'/{layout}',
[Controllers\API\LayoutManagementController::class, 'update'],
)->name('layouts.update');
});
// Users.
$router->put('/users/{user}', [TeamMemberController::class, 'update'])
->middleware(['permission:' . PermissionEnum::MANAGE_USERS->value])
->name('api.users.update');
$router->delete('/users/{user}', [TeamMemberController::class, 'deactivate'])
->middleware(['permission:' . PermissionEnum::MANAGE_USERS->value])
->name('api.users.deactivate');
$router->group(
[
'prefix' => 'vocabulary',
'middleware' => 'can:manage,' . Vocabulary::class,
],
static function (Router $router): void {
$router
->get('/', [VocabularyController::class, 'list'])
->name('api.vocabulary.index');
$router
->post('/', [VocabularyController::class, 'update'])
->name('api.vocabulary.create');
$router->group(['prefix' => '{vocabulary}'], static function (Router $router): void {
$router
->put('/', [VocabularyController::class, 'update'])
->middleware('can:update,vocabulary')
->name('api.vocabulary.update');
$router
->delete('/', [VocabularyController::class, 'delete'])
->middleware('can:delete,vocabulary')
->name('api.vocabulary.delete');
});
},
);
$router->group(['prefix' => 'ai-context'], static function (Router $router): void {
$router->get('/', [TeamAiContextController::class, 'index'])
->name('api.ai_context.get');
$router->post('/', [TeamAiContextController::class, 'store'])
->name('api.ai_context.store');
});
$router->group(['prefix' => 'ai-automation'], static function (Router $router): void {
$router->post('/fields/test-prompt', [TeamAiAutomationController::class, 'testCrmAiPrompt'])
->name('api.automation.templates.fields.test-prompt');
// List CRM fields per object type
$router->get('/fields/{objectType}', [TeamAiAutomationController::class, 'fields'])
->name('api.automation.fields');
// List DealStages fields per object type
$router->get('/stages', [TeamAiAutomationController::class, 'stages'])
->name('api.automation.stages');
// Create CRM AI template
$router->post('/templates', [TeamAiAutomationController::class, 'createTemplate'])
->name('api.automation.templates.create');
// Export CRM updates
$router->post('/templates/export-crm-updates', [TeamAiAutomationController::class, 'exportTemplateCrmUpdates'])
->name('api.automation.templates.export-crm-updates');
// Update CRM AI template
$router->put('/templates/{crmTemplate}', [TeamAiAutomationController::class, 'updateTemplate'])
->name('api.automation.templates.update');
// Delete CRM AI template
$router->delete('/templates/{crmTemplate}', [TeamAiAutomationController::class, 'deleteTemplate'])
->name('api.automation.templates.delete');
// List all CRM AI templates
$router->get('/templates', [TeamAiAutomationController::class, 'templates'])
->name('api.automation.templates.list');
// Create CRM AI template field
$router->post('/templates/{crmTemplate}/fields', [TeamAiAutomationController::class, 'createField'])
->name('api.automation.templates.fields.create');
// Update CRM AI template field
$router->put('/templates/{crmTemplate}/fields/{crmTemplateField}', [TeamAiAutomationController::class, 'updateField'])
->name('api.automation.templates.fields.update');
// Delete CRM AI template field
$router->delete('/templates/{crmTemplate}/fields/{crmTemplateField}', [TeamAiAutomationController::class, 'deleteField'])
->name('api.automation.templates.fields.delete');
});
$router->group(['prefix' => 'ai-call-scoring'], static function (Router $router): void {
// Create AI scorecard
$router->post('/ai-scorecards', [Controllers\API\AiCallScoring\AiScorecardController::class, 'createAiScorecard'])
->name('api.ai-call-scoring.ai-scorecards.create');
// Update AI scorecard
$router->put('/ai-scorecards/{aiScorecard}', [Controllers\API\AiCallScoring\AiScorecardController::class, 'updateAiScorecard'])
->name('api.ai-call-scoring.ai-scorecards.update');
// Delete AI scorecard
$router->delete('/ai-scorecards/{aiScorecard}', [Controllers\API\AiCallScoring\AiScorecardController::class, 'deleteAiScorecard'])
->name('api.ai-call-scoring.ai-scorecards.delete');
// Test AI scorecard prompt
$router->post(
'/ai-scorecards/{aiScorecard}/test-prompt',
[
Controllers\API\AiCallScoring\AiScorecardController::class,
'testAiScorecardPrompt',
]
)
->name('api.ai-call-scoring.ai-scorecards.test-prompt');
// Create AI Scorecard rule
$router->post('/ai-scorecards/{aiScorecard}/ai-scorecard-rules', [Controllers\API\AiCallScoring\AiScorecardRuleController::class, 'createRule'])
->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.create');
// Update AI Scorecard rule
$router->put('/ai-scorecards/{aiScorecard}/ai-scorecard-rules/{aiScorecardRule}', [Controllers\API\AiCallScoring\AiScorecardRuleController::class, 'updateAiScorecardRule'])
->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.update');
// Delete AI Scorecard rule
$router->delete('/ai-scorecards/{aiScorecard}/ai-scorecard-rules/{aiScorecardRule}', [Controllers\API\AiCallScoring\AiScorecardRuleController::class, 'deleteAiScorecardRule'])
->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.delete');
});
// Theme, topics, triggers
$router->get('/themes', [ThemeController::class, 'list']);
$router
->post('/themes', [ThemeController::class, 'updateTheme'])
->middleware('can:manage,' . PlaybackTheme::class)
->name('api.theme.create');
$router->group(
[
'prefix' => 'theme/{theme}',
'middleware' => 'can:update,theme',
],
static function (Router $router): void {
$router
->put('/', [ThemeController::class, 'updateTheme'])
->name('api.theme.update');
$router
->delete('/', [ThemeController::class, 'deleteTheme'])
->middleware('can:delete,theme')
->name('api.theme.delete');
$router
->post('/topics', [TopicController::class, 'updateTopic'])
->middleware('can:createTopic,theme')
->name('api.topic.create');
$router->group(
[
'prefix' => 'topic/{topic}',
'middleware' => 'can:update,topic',
],
static function (Router $router): void {
$router
->put('/', [TopicController::class, 'updateTopic'])
->name('api.topic.update');
$router
->delete('/', [TopicController::class, 'deleteTopic'])
->middleware('can:delete,topic')
->name('api.topic.delete');
$router
->post('/triggers', [TopicTriggerController::class, 'updateTrigger'])
->middleware('can:createTrigger,topic')
->name('api.topic_trigger.create');
$router->group(
[
'prefix' => 'trigger/{topicTrigger}',
'middleware' => 'can:update,topicTrigger',
],
static function (Router $router): void {
$router
->put('/', [TopicTriggerController::class, 'updateTrigger'])
->name('api.topic_trigger.update');
$router
->delete('/', [TopicTriggerController::class, 'deleteTrigger'])
->middleware('can:delete,topicTrigger')
->name('api.topic_trigger.delete');
},
);
},
);
},
);
$router->post('/themes/import', [Controllers\API\Themes\ImportTopicTriggerController::class, 'importThemes']);
$router->get('/themes/export', [Controllers\API\Themes\ExportTopicTriggerController::class, 'exportThemes']);
// Auto-scoring
$router->group(['prefix' => '/scorecards'], static function (Router $router) {
$router->get('/', [Controllers\API\Scorecards\ScorecardController::class, 'list']);
$router->post('/', [Controllers\API\Scorecards\ScorecardController::class, 'create']);
$router->delete('/{scorecard}', [
Controllers\API\Scorecards\ScorecardController::class,
'delete',
]);
$router->post('/validate-name', [
Controllers\API\Scorecards\ScorecardController::class,
'validateNameExists',
]);
$router->get('/enabled-scorecard', [
Controllers\API\Scorecards\ScorecardController::class,
'getEnabledScorecard',
]);
$router->get('/affected-scorecards', [
Controllers\API\Scorecards\ScorecardController::class,
'getAffectedScorecards',
]);
$router->group(['prefix' => '/{scorecard}'], static function (Router $router) {
$router->put('/', [
Controllers\API\Scorecards\ScorecardController::class,
'update',
]);
$router->delete('/', [
Controllers\API\Scorecards\ScorecardController::class,
'delete',
]);
$router->post('/rules', [
Controllers\API\Scorecards\ScorecardRuleController::class,
'create',
]);
$router->post('/rules/{scorecardRule}', [
Controllers\API\Scorecards\ScorecardRuleController::class,
'update',
]);
$router->delete('/rules/{scorecardRule}', [
Controllers\API\Scorecards\ScorecardRuleController::class,
'delete',
]);
$router->post('/rules/{scorecardRule}/update-order', [
Controllers\API\Scorecards\ScorecardRuleController::class,
'updateOrder',
]);
});
});
// Coaching Playbook.
Route::get('/playbooks', [PlaybookController::class, 'all']);
Route::get('/playbooksTree', [PlaybookController::class, 'tree']);
Route::put('/playbooks/{playbook}', [PlaybookController::class, 'update']);
Route::post('/playbooks', [PlaybookController::class, 'store']);
Route::delete('/playbooks/{playbook}', [PlaybookController::class, 'destroy']);
Route::prefix('/playbooks/{playbook}')->group(static function () {
// Playbook Categories.
Route::get('/categories', [PlaybookCategoryController::class, 'all']);
Route::put('/categories/sequence', [PlaybookCategoryController::class, 'sequence']); // Respect order.
Route::put('/categories/{category}', [PlaybookCategoryController::class, 'update']);
Route::post('/categories', [PlaybookCategoryController::class, 'store']);
Route::post('/test-prompt', [PlaybookController::class, 'testAiActivityTypePrompt']);
Route::post('/prompt-suggestion', [PlaybookController::class, 'getPromptSuggestion']);
Route::delete('/categories/{category}', [PlaybookCategoryController::class, 'destroy']);
Route::prefix('/categories/{category}')->group(static function () {
// Coaching Sections
Route::get('/coaching-section', [Controllers\Settings\Coaching\SectionsController::class, 'all']);
Route::put('/coaching-section/sequence', [Controllers\Settings\Coaching\SectionsController::class, 'sequence']);
Route::put('/coaching-section/{coachingSection}', [Controllers\Settings\Coaching\SectionsController::class, 'update']);
Route::post('/coaching-section', [Controllers\Settings\Coaching\SectionsController::class, 'store']);
Route::delete('/coaching-section/{coachingSection}', [Controllers\Settings\Coaching\SectionsController::class, 'destroy']);
Route::prefix('coaching-section/{coachingSection}')->group(static function () {
// Coaching Section Criteria
Route::get('/coaching-section-criterion', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'all']);
Route::put('/coaching-section-criterion/sequence', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'sequence']);
Route::put('/coaching-section-criterion/{coachingSectionCriterion}', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'update']);
Route::post('/coaching-section-criterion', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'store']);
Route::delete('/coaching-section-criterion/{coachingSectionCriterion}', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'destroy']);
});
});
});
},
);
// List all AI scorecards (accessible to all team members, no MANAGE_TEAM required)
$router->get('/ai-call-scoring/ai-scorecards', [Controllers\API\AiCallScoring\AiScorecardController::class, 'aiScorecards'])
->name('api.ai-call-scoring.ai-scorecards.list');
$router->middleware(['permission:' . PermissionEnum::MANAGE_ORGANIZATION_SETTINGS->value])
->group(static function (Router $router): void {
// Job Titles.
$router->get('/job-titles', [JobTitleController::class, 'all']);
$router->put('/job-titles/{job}', [JobTitleController::class, 'update']);
$router->post('/job-titles', [JobTitleController::class, 'store']);
$router->delete('/job-titles/{job}', [JobTitleController::class, 'destroy']);
// Team Settings.
$router->put('/', [TeamSettingsController::class, 'update']);
$router->put('/notifications', [TeamSettingsController::class, 'updateNotifications']);
$router->put('/team-conference', [TeamConferenceSettingsController::class, 'update']);
$router->put('/team-coaching', [TeamCoachingSettingsController::class, 'update']);
$router->put('/team-softphone', [TeamSoftphoneSettingsController::class, 'update']);
$router->put('/owner', [Controllers\Settings\Teams\OrganizationSettingsController::class, 'updateOwner']);
$router->put('/team-recording', [TeamRecordingSettingsController::class, 'update'])
->middleware(['permission:' . PermissionEnum::MANAGE_RECORDING->value]);
// Key Moments.
$router->get('/moments/{moment}', [Controllers\Settings\MomentController::class, 'show']);
$router->put('/moments/{moment}', [Controllers\Settings\MomentController::class, 'update']);
$router->post('/moments', [Controllers\Settings\MomentController::class, 'store']);
$router->put('/activity', [TeamActivityController::class, 'store']);
// Team Domains.
$router->get('/domains', [Controllers\Settings\Teams\TeamDomainsController::class, 'all']);
$router->post('/domains', [Controllers\Settings\Teams\TeamDomainsController::class, 'create']);
$router->delete('/domains/{teamDomain}', [Controllers\Settings\Teams\TeamDomainsController::class, 'destroy']);
});
});
});
});
// Integrations
$router->group(['middleware' => 'permission:' . PermissionEnum::MANAGE_INTEGRATIONS->value], static function (Router $router): void {
$router->post('/integrations', [IntegrationController::class, 'internal'])
->name('api.integrations.internal');
$router->put('/integrations', [IntegrationController::class, 'toggleStatus'])
->name('api.integrations.toggle_status');
$router->delete('/integrations/{provider}', [IntegrationController::class, 'delete'])
->name('api.integrations.delete');
});
$router->get('/integrations', [IntegrationController::class, 'all'])
->middleware('permission:' . PermissionEnum::READ_INTEGRATIONS->value)
->name('api.integrations.index');
// Slack API for getting slack channels list
$router->get('{notificationProvider}/channels', [Controllers\NotificationProviderController::class, 'channels']);
// Team actions. XXX: These all need moving out to their own controllers.
$router->group(['prefix' => 'organizations'], static function (Router $router): void {
$router->get('current', [TeamController::class, 'current']);
$router->group(['prefix' => '{team}', 'middleware' => ['teamMember']], static function (Router $router): void {
$router->get('/', [TeamController::class, 'show']);
$router->get('/categories', [TeamController::class, 'categories']);
$router->get('/stages', [TeamController::class, 'stages']);
$router->get('/users', [OrganizationMembersController::class, 'index'])
->name('organization.members.index');
$router
->get('/users/download', [OrganizationMembersController::class, 'download'])
->middleware('permission:' . PermissionEnum::MANAGE_USERS->value)
->name('organization.members.download');
$router->get('/licensed-roles', [OrganizationLicensesController::class, 'index'])
->middleware('permission:' . PermissionEnum::MANAGE_BILLING->value)
->name('organization.licensed-roles.index');
$router->get('/invitations', [TeamController::class, 'invitations']);
$router->get('/groups', [TeamController::class, 'groups']);
$router->delete('/groups/{group}', [TeamController::class, 'deleteGroup'])
->middleware(['permission:' . PermissionEnum::DELETE_TEAM->value])
->name('api.groups.delete');
$router->get('/job-titles', [TeamController::class, 'jobTitles']);
$router->get('/slugs', [TeamController::class, 'slugs']);
$router->put('/api-token', [TeamController::class, 'generateApiToken'])
->middleware(['permission:' . PermissionEnum::MANAGE_ORGANIZATION_SETTINGS->value]);
$router->get('/key-moments', [MomentController::class, 'all']);
});
});
// Internal Kiosk. This whole section will be moved out to a separate file
$router
->prefix('kiosk')
->middleware('can:kiosk,' . User::class)
->group(static function (Router $router): void {
// Partner actions.
$router->get('/partners', [PartnersController::class, 'index']);
// User actions.
$router->post('/users/search', [SearchController::class, 'performBasicSearch']);
// Team actions.
$router->prefix('organizations')->group(static function (Router $router): void {
$router->get('/', [OrganizationsController::class, 'show']);
$router->put('/{team}', [OrganizationController::class, 'edit'])
->name('kiosk.organizations.edit');
$router->get('/{team}/users', [OrganizationMembersController::class, 'index'])
->name('kiosk.organization.members.index');
$router->get('onboardable', [OnboardController::class, 'available']);
$router->delete('/{team}', [OrganizationsController::class, 'deactivateAccounts']);
});
// Automated reports
// api/v1/kiosk/automated-reports
$router->prefix('automated-reports')->group(static function (Router $router): void {
$router->get('/form-data', [AutomatedReportsController::class, 'getCreateForm']);
$router->get('/form-data/{reportUuid}', [AutomatedReportsController::class, 'getEditForm']);
$router->post('/filters', [AutomatedReportsController::class, 'getFilters']);
$router->post('/', [AutomatedReportsController::class, 'create']);
$router->put('/{reportUuid}', [AutomatedReportsController::class, 'update']);
$router->patch('/{reportUuid}', [AutomatedReportsController::class, 'partialUpdate']);
$router->get('/', [AutomatedReportsController::class, 'list']);
$router->get('/{reportUuid}', [AutomatedReportsController::class, 'get']);
$router->delete('/{reportUuid}', [AutomatedReportsController::class, 'delete']);
$router->post('/activities-count', [AutomatedReportsController::class, 'getActivitiesCount']);
$router->get('/{reportUuid}/reports-count', [AutomatedReportsController::class, 'getReportsCount']);
});
// Activity actions.
$router->post('/activity/search', [SearchController::class, 'performActivitySearch']);
$router->prefix('activity/{activity}')->group(static function (Router $router): void {
$router->post('check-playable', [SearchController::class, 'performActivityCheckPlayable']);
$router->post('reset-crm-log', [SearchController::class, 'performResetCrmLogActivity']);
$router->get('diarize-via-transcript', [KioskActivityController::class, 'diarizeViaTranscript']);
$router->post('diarize-via-transcript', [KioskActivityController::class, 'diarizeViaTranscript']);
$router->get('media-pipeline', [MediaPipelineController::class, 'getPipes']);
$router->post('media-pipeline', [MediaPipelineController::class, 'updatePipe']);
$router->post('language', [KioskActivityController::class, 'updateLanguage']);
$router->post('trim', [KioskActivityController::class, 'trimActivity']);
$router->get('troubleshoot', [KioskActivityController::class, 'troubleshootActivity'...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79497
|
2787
|
55
|
2026-05-28T06:31:58.468272+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949918468_m2.jpg...
|
PhpStorm
|
faVsco.js – api.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormEV faVscols~ProjectvViewNeWENNCCodeRefacto PhpStormEV faVscols~ProjectvViewNeWENNCCodeRefactorRurToolsWindow$ JY-20915-fix-missing-header-text-rolay~© Kemelphp© SyneMailbox.php© Field,phpphe api.php *© CrmController.phpE custom.logE laravellogSF jiminny@localhost) x 4 HSJocal ([iminny@localhost)A console (PROD]A console (EU]© BaseController.phpcomposer.json& DockerfileTextRelayServiceTest,phpDo jminny phpE env.productionE envA console (STAGING)@ClientTokenController.phpemconto trono<?phpTAWAVDA000TeAutosih acrwitiesaowoalto Veirtomontenamespace Jininny\Http\Controllers\API;OUeahxConouon=234IIN users u 1.nc->1: ON a.user_id = u.10TERE©LanguageController.php236© LayoutManagementContre237class KraController extends Controller© LiveFeedController.php238©) MeetinasController.oholc) Messagecontro er oho© MetadataController.ohdc) MooileSettinascontro.erC) Momentcontro er.ond© NudgeController.phpE) NumberAllocatorControlle248private const string MESSAGE_GENERAL_EXCEPTION,SEARCHING = 'Sorry, an internal error occurred whilst $ 243usao242private const string MESSAGE_GENERAL_EXCEPTION = 'Sorry, an internal error occurred.':2433 usages244private ?ServiceInterface ScraService = null;245a.status = 'completed"Ano uurd to bind 6411800-1608-4201-8726-4757079da08eD = u.uusAND a.deleted_at IS NULLANDSXTESSELECT 1 FROM tracks tWHERE t.activity_id = a.idAND t.type IN ('audio', "video')EDER BY a.actual_start,time DESCMIT 25:OrganizationLicensesCont© OrganizationRetentionPoslcetonr hontd setoote© OrganizationSyncControlkPartnerController, php© PhoneNumberController.pPlaybackController.phpPlaylistController.phpScimController.phpSidekickController.php© SoftphoneController.php© SsoController.php© SubscriptionController.phc101© TeamAlAutomationControl©TeamAlContextController.© TeamController.php©TeaminsightsController.ph©TranscriptionController.ph©TranslationController.php©UserController.php© VocabularyController.php109› DAuth› D CustomerApi› O Internal~ O Kiosk> Teams@ActivityController.phpБВВВ© AutomatedReportsControlcbachbaard eontroe.ondclimoerconationControeo© MediaPipelineController.pl8 Oraacizatians Controlor oiPartnersController.phpeorntiesantraoenhrpublic function __construct (Response Sresponse) (...* Method for searching for remote records by nome.* Bparan Request Srequest* Ethrows ContainerExceptionInterface* @theows NotFoundExceptionInterface* Greturn nixedpublic function search(Request Srequest): nixed(...;* Method for retrieving remote opportunities by account or contact.* BRacan Request Srequest* Ethrows ContainerExceptionInterface* Ethrows NotFoundExceptionInterface* Breturn mixedpublic function opportunities(Request Srequest): nixedf...* Yerhod con perareuine recote taske hu licen274caener Reauest Soecuesy*Chnome kontesnensycontsantntantee* Cthnome NotSoundSycanttonTotanfaca* Bretucn mixed68 fminny ~021 41 418 X2 X8 Ailect * fron teans where id = 19:flect * fron crn_configurations where provider = 'Ripedcive':ELECTCONCAT(u.id, CASE WHEN U.id = t.ouner_id THEN • (onner)' ELSE ** END) AS user_id,U.ehazlSa.xt.ouner_id FROM social_accounts sawusers uon urs sansoeaoletIIN teans t 1.n<->1: on t.id = u.team_idJERE u,tean 1d = 19 and sa,onoyiden = "oipedoive':*XUhSo088cc0u11smex28abo%DATe sochal accounts set onoviden usen token = "Mu:ADCA:--21 K2yuuuaLos2hwo9crunklok4el09cinXoo dAEchohdoVasnyichEynoysoines = 998919941ERE 1031516'provider_user_token": "vlu:AQIBAHJ-LzTNK2yuuuaLgifzhHb9crUNKTpk«F1Q9rjnXqp_6AEQhDhDQVa1nv#CHEvnpvSEAAAAfjB8Bgkqhki69w9BBw35ilect * fron crn field values:ilect * fron crn_fields where type = 'nulti-picklist';LECT * FROM Crn_ Layouts WHERE uuid_to_bin(*7C327871-4c25-4c56-9a0f-44c5a849d65c') = uuid;ELECT * FROM crn_layout_entities WHERE crn_layout_id = 282;ELECT * FROM crn_fields WHERE id = 3014; # 1885ELECT * FROM crn_field_vatues WHERE crn_field_id = 3014;00%LXThu 28 May 9:31:58U TextRelayServiceTest~ner hensewiet+0.can I test it locally first. if I place env from stagingYes. The service relies on a few things you'd need in place:1. Credentials file The constructor expects storage/text-relay.json (a Google service account JSON key file)Gmbtrom sthaind and oince it there2. .env values to copy from stagingGOOGLE TEXTUSERECOOGLE TEXTI HASTGOOGLE_TEXT_RELAY_TOPIC=DEPLOY _REGION=the cnail nailbox address# e.g. txt.jiminny.com or txt.staging.jiminny.com# the Pub/Sub topie name* eu or us3. Run the sync manually via tinker (inside docker_lanp_1):D bashdocker exec -it docker_lamp_1 php artisan tinker• 0app(\Jininny\ServicesVMail\TextRelayServices:class)->sync();Caveat: The service reads from Gmail history and dispatches jobs to the queue. If you don't want it to actuallsend SMS, make sure QUEUE_CONNECTICN-sync is not set (or use a test queue), or just call isForCurrentEnvironmtioh.Ssvc = new class extends \JiminnylServicesVa1l\TextRelayService ( public function _constructlsom Serviceassvc-soctServicelcontiatainny.googletextI then sinsoect au eessade canuai. 1sasg = SgnaitService-susers_gessages-sget(config(*Jiainny-9009le_text_user*), "THE_MESSAGE_ID*)collect (Sasg->getPayload()-»getHeaders())->pluck("value',thut wey von can Mrity what handare tra nehhilm oraesot do ttat macesos alote tha ull evoc muneAsk anything (XOL)- @ eodeAdhotvaries for other lanquages. (yesterday 15:44)Mwnderhimeoeh2 4 space:...
|
NULL
|
9211836217730593084
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormEV faVscols~ProjectvViewNeWENNCCodeRefacto PhpStormEV faVscols~ProjectvViewNeWENNCCodeRefactorRurToolsWindow$ JY-20915-fix-missing-header-text-rolay~© Kemelphp© SyneMailbox.php© Field,phpphe api.php *© CrmController.phpE custom.logE laravellogSF jiminny@localhost) x 4 HSJocal ([iminny@localhost)A console (PROD]A console (EU]© BaseController.phpcomposer.json& DockerfileTextRelayServiceTest,phpDo jminny phpE env.productionE envA console (STAGING)@ClientTokenController.phpemconto trono<?phpTAWAVDA000TeAutosih acrwitiesaowoalto Veirtomontenamespace Jininny\Http\Controllers\API;OUeahxConouon=234IIN users u 1.nc->1: ON a.user_id = u.10TERE©LanguageController.php236© LayoutManagementContre237class KraController extends Controller© LiveFeedController.php238©) MeetinasController.oholc) Messagecontro er oho© MetadataController.ohdc) MooileSettinascontro.erC) Momentcontro er.ond© NudgeController.phpE) NumberAllocatorControlle248private const string MESSAGE_GENERAL_EXCEPTION,SEARCHING = 'Sorry, an internal error occurred whilst $ 243usao242private const string MESSAGE_GENERAL_EXCEPTION = 'Sorry, an internal error occurred.':2433 usages244private ?ServiceInterface ScraService = null;245a.status = 'completed"Ano uurd to bind 6411800-1608-4201-8726-4757079da08eD = u.uusAND a.deleted_at IS NULLANDSXTESSELECT 1 FROM tracks tWHERE t.activity_id = a.idAND t.type IN ('audio', "video')EDER BY a.actual_start,time DESCMIT 25:OrganizationLicensesCont© OrganizationRetentionPoslcetonr hontd setoote© OrganizationSyncControlkPartnerController, php© PhoneNumberController.pPlaybackController.phpPlaylistController.phpScimController.phpSidekickController.php© SoftphoneController.php© SsoController.php© SubscriptionController.phc101© TeamAlAutomationControl©TeamAlContextController.© TeamController.php©TeaminsightsController.ph©TranscriptionController.ph©TranslationController.php©UserController.php© VocabularyController.php109› DAuth› D CustomerApi› O Internal~ O Kiosk> Teams@ActivityController.phpБВВВ© AutomatedReportsControlcbachbaard eontroe.ondclimoerconationControeo© MediaPipelineController.pl8 Oraacizatians Controlor oiPartnersController.phpeorntiesantraoenhrpublic function __construct (Response Sresponse) (...* Method for searching for remote records by nome.* Bparan Request Srequest* Ethrows ContainerExceptionInterface* @theows NotFoundExceptionInterface* Greturn nixedpublic function search(Request Srequest): nixed(...;* Method for retrieving remote opportunities by account or contact.* BRacan Request Srequest* Ethrows ContainerExceptionInterface* Ethrows NotFoundExceptionInterface* Breturn mixedpublic function opportunities(Request Srequest): nixedf...* Yerhod con perareuine recote taske hu licen274caener Reauest Soecuesy*Chnome kontesnensycontsantntantee* Cthnome NotSoundSycanttonTotanfaca* Bretucn mixed68 fminny ~021 41 418 X2 X8 Ailect * fron teans where id = 19:flect * fron crn_configurations where provider = 'Ripedcive':ELECTCONCAT(u.id, CASE WHEN U.id = t.ouner_id THEN • (onner)' ELSE ** END) AS user_id,U.ehazlSa.xt.ouner_id FROM social_accounts sawusers uon urs sansoeaoletIIN teans t 1.n<->1: on t.id = u.team_idJERE u,tean 1d = 19 and sa,onoyiden = "oipedoive':*XUhSo088cc0u11smex28abo%DATe sochal accounts set onoviden usen token = "Mu:ADCA:--21 K2yuuuaLos2hwo9crunklok4el09cinXoo dAEchohdoVasnyichEynoysoines = 998919941ERE 1031516'provider_user_token": "vlu:AQIBAHJ-LzTNK2yuuuaLgifzhHb9crUNKTpk«F1Q9rjnXqp_6AEQhDhDQVa1nv#CHEvnpvSEAAAAfjB8Bgkqhki69w9BBw35ilect * fron crn field values:ilect * fron crn_fields where type = 'nulti-picklist';LECT * FROM Crn_ Layouts WHERE uuid_to_bin(*7C327871-4c25-4c56-9a0f-44c5a849d65c') = uuid;ELECT * FROM crn_layout_entities WHERE crn_layout_id = 282;ELECT * FROM crn_fields WHERE id = 3014; # 1885ELECT * FROM crn_field_vatues WHERE crn_field_id = 3014;00%LXThu 28 May 9:31:58U TextRelayServiceTest~ner hensewiet+0.can I test it locally first. if I place env from stagingYes. The service relies on a few things you'd need in place:1. Credentials file The constructor expects storage/text-relay.json (a Google service account JSON key file)Gmbtrom sthaind and oince it there2. .env values to copy from stagingGOOGLE TEXTUSERECOOGLE TEXTI HASTGOOGLE_TEXT_RELAY_TOPIC=DEPLOY _REGION=the cnail nailbox address# e.g. txt.jiminny.com or txt.staging.jiminny.com# the Pub/Sub topie name* eu or us3. Run the sync manually via tinker (inside docker_lanp_1):D bashdocker exec -it docker_lamp_1 php artisan tinker• 0app(\Jininny\ServicesVMail\TextRelayServices:class)->sync();Caveat: The service reads from Gmail history and dispatches jobs to the queue. If you don't want it to actuallsend SMS, make sure QUEUE_CONNECTICN-sync is not set (or use a test queue), or just call isForCurrentEnvironmtioh.Ssvc = new class extends \JiminnylServicesVa1l\TextRelayService ( public function _constructlsom Serviceassvc-soctServicelcontiatainny.googletextI then sinsoect au eessade canuai. 1sasg = SgnaitService-susers_gessages-sget(config(*Jiainny-9009le_text_user*), "THE_MESSAGE_ID*)collect (Sasg->getPayload()-»getHeaders())->pluck("value',thut wey von can Mrity what handare tra nehhilm oraesot do ttat macesos alote tha ull evoc muneAsk anything (XOL)- @ eodeAdhotvaries for other lanquages. (yesterday 15:44)Mwnderhimeoeh2 4 space:...
|
79496
|
NULL
|
NULL
|
NULL
|
|
79496
|
2787
|
54
|
2026-05-28T06:31:55.875696+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949915875_m2.jpg...
|
PhpStorm
|
faVsco.js – CrmController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
48
9
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use DomainException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Jiminny\Contracts\Services\Crm\Provider\SalesforceInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\ServiceUnavailableException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\AccountTransformer;
use Jiminny\Http\Transformers\ContactTransformer;
use Jiminny\Http\Transformers\LayoutTransformer;
use Jiminny\Http\Transformers\LeadTransformer;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Models\Account;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Playbook;
use Jiminny\Models\User;
use Jiminny\Rules\CrmReference;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class CrmController extends Controller
{
private const string MESSAGE_GENERAL_EXCEPTION_SEARCHING = 'Sorry, an internal error occurred whilst searching.';
private const string MESSAGE_GENERAL_EXCEPTION = 'Sorry, an internal error occurred.';
private ?ServiceInterface $crmService = null;
public function __construct(Response $response)
{
parent::__construct($response);
}
/**
* Method for searching for remote records by name.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function search(Request $request): mixed
{
$allowedScopes = [
'lead',
'account',
'contact',
'account-business',
'account-person',
'contact-business',
'contact-person',
];
$request->validate([
'scopes' => 'required|in:' . implode(',', $allowedScopes) . '|array',
'name' => 'required|string|max:100|min:2',
'limit' => 'min:1|max:20',
'offset' => 'min:0',
]);
$scopes = $request->input('scopes');
$name = $request->input('name');
$limit = $request->input('limit', 20);
$offset = $request->input('offset', 0);
$user = $this->getUserFromRequest($request);
try {
$crmService = $this->getCrmServiceWithActiveUser($user);
$crmService->setPage($limit, $offset);
$response = $crmService->find($name, $scopes);
} catch (SocialAccountTokenInvalidException $exception) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (CrmException $exception) {
$response = [];
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return $response;
}
/**
* Method for retrieving remote opportunities by account or contact.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function opportunities(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
try {
$crmProvider = $team->crm->provider;
$request->validate([
'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],
'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],
]);
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($this->request->has('contactId')) {
$contactId = $this->request->input('contactId');
$contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();
// Contact does not exist locally, import it.
if ($contact === null) {
$contact = $crmService->syncContact($contactId);
}
$accountId = $contact->account_id ? $contact->account->crm_provider_id : null;
} else {
$contactId = null;
$accountId = $this->request->input('accountId');
}
$response = $crmService->findOpportunities($accountId, $contactId, $user->getId());
} catch (\InvalidArgumentException $exception) {
$response = $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException $exception) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return $response;
}
/**
* Method for retrieving remote tasks by user.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function activities(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
$crmProvider = $team->crm->provider;
$request->validate([
'objectType' => 'in:lead,contact,account',
'prospectId' => new CrmReference($crmProvider),
'opportunityId' => new CrmReference($crmProvider),
]);
try {
$opportunityId = $request->input('opportunityId');
$objectType = $request->input('objectType');
$objectId = $request->input('prospectId');
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($objectType === null
&& $crmService instanceof SupportsObjectTypeParseInterface
) {
$objectType = $crmService->parseObjectType($objectId);
}
// Take the activity type from the Playbook (default to first for orphaned users).
if ($user->group_id) {
$playbook = $user->group->playbook;
} else {
$playbook = $user->team->playbooks()->first();
// fix empty playbook
if ($playbook === null) {
throw new \InvalidArgumentException('Please configure a Playbook first.');
}
}
if ($crmService instanceof SalesforceInterface) {
/**
* Salesforce support Tasks and Events,
* other crms support only Tasks
*/
$activities = $playbook->activity_type === Playbook::ACTIVITY_TYPE_TASK
? $crmService->getTasks($objectType, $objectId, $opportunityId)
: $crmService->getEvents($objectType, $objectId, $opportunityId);
} else {
$activities = $crmService->getTasks($objectType, $objectId, $opportunityId);
}
} catch (\InvalidArgumentException $exception) {
return $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException $exception) {
return $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
return $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
return $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return [
'activities' => $activities,
'playbookActivityType' => $playbook->activity_type,
];
}
/**
* Method for retrieving remote customer details.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function customers(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
$crmProvider = $team->crm->provider;
$request->validate([
'objectType' => 'in:lead,contact,account,opportunity,undefined',
'providerId' => new CrmReference($crmProvider),
'phoneNumber' => 'phone:INTERNATIONAL,US,' . $user->country_code,
]);
$objectType = $request->input('objectType');
$objectId = $request->input('providerId');
$phoneNumber = $request->input('phoneNumber');
$this->response
->getManager()
->setSerializer(new JsonSerializer());
try {
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($objectId) {
if (($objectType === null || $objectType === 'undefined')
&& $crmService instanceof SupportsObjectTypeParseInterface
) {
$objectType = $crmService->parseObjectType($objectId);
}
switch ($objectType) {
case 'lead':
$lead = $this->getLead($objectId);
$response = $this->response->withItem($lead, new LeadTransformer());
break;
case 'account':
$account = $this->getAccount($objectId);
$response = $this->response->withItem($account, new AccountTransformer());
break;
case 'contact':
$contact = $this->getContact($objectId);
$response = $this->response->withItem($contact, new ContactTransformer());
break;
case 'opportunity':
$opportunity = $this->getOpportunity($objectId);
$response = $this->response->withItem($opportunity->account, new AccountTransformer());
break;
default:
$response = $this->response->errorWrongArgs('Sorry, we don\'t support messaging this type of record.');
break;
}
} elseif ($phoneNumber) {
[$lead, $account, , $contact] = $crmService->matchByPhone(
$phoneNumber,
null,
$user->getId()
);
if ($lead) {
$response = $this->response->withItem($lead, new LeadTransformer());
} elseif ($account) {
$response = $this->response->withItem($account, new AccountTransformer());
} elseif ($contact) {
$response = $this->response->withItem($contact, new ContactTransformer());
} else {
$response = $this->response->errorNotFound('Customer not found.');
}
} else {
$response = $this->response->errorWrongArgs('No search data provided.');
}
} catch (\InvalidArgumentException $exception) {
$response = $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION);
}
return $response;
}
/**
* Rest method for retrieving accounts.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function accounts(): mixed
{
$user = $this->getUserFromRequest($this->request);
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'accountId' => new CrmReference($crmProvider),
]);
$this->response->getManager()->setSerializer(new JsonSerializer());
if ($this->request->has('accountId')) {
$accountId = $this->request->input('accountId');
try {
$account = $this->getAccount($accountId);
$response = $this->response->withItem($account, new AccountTransformer());
} catch (DomainException) {
$response = $this->response->errorNotFound('Record not found.');
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
} else {
$response = $this->response->withCollection($user->team->accounts, new AccountTransformer());
}
return $response;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $accountId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return Account
*/
private function getAccount(string $accountId): Account
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$account = $team->crm->accounts()->where('crm_provider_id', $accountId)->first();
if ($account instanceof Account) {
return $account;
}
// Account does not exist locally, import it.
try {
return $this->getCrmServiceWithActiveUser($user)->syncAccount($accountId);
} catch (SocialAccountTokenInvalidException $exception) {
return $this->response->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.'
);
}
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $opportunityId
*
* @throws DomainException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Opportunity
*/
private function getOpportunity(string $opportunityId): Opportunity
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if (! $opportunity instanceof Opportunity) {
$crmService = $this->getCrmServiceWithActiveUser($user);
$opportunity = $crmService->syncOpportunity($opportunityId);
}
// Sanity check.
if ($user->team_id !== $opportunity->account->team_id) {
throw new DomainException('Opportunity not found.');
}
return $opportunity;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $contactId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Contact
*/
private function getContact(string $contactId): Contact
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$crmService = $this->getCrmServiceWithActiveUser($user);
$contact = $crmService->syncContact($contactId);
}
return $contact;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $leadId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Lead
*/
private function getLead(string $leadId): Lead
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$lead = $team->crm->leads()->where('crm_provider_id', $leadId)->first();
if ($lead instanceof Lead) {
return $lead;
}
// Lead does not exist locally, import it.
return $this->getCrmServiceWithActiveUser($user)->syncLead($leadId);
}
/**
* Rest method for retrieving contacts.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function contacts(): mixed
{
$user = $this->request->user();
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],
'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],
]);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
try {
// Determine if they wish to retrieve a single contact or multiple for an account.
if ($this->request->has('contactId')) {
$contactId = $this->request->input('contactId');
$contact = $this->getContact($contactId);
$response = $this->response->withItem($contact, new ContactTransformer());
} else {
$accountId = $this->request->input('accountId');
$account = $this->getAccount($accountId);
$response = $this->response->withCollection($account->contacts, new ContactTransformer());
}
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
return $response;
}
/**
* Rest method for retrieving leads.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function leads(): mixed
{
$user = $this->request->user();
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'leadId' => new CrmReference($crmProvider),
]);
$this->response
->getManager()
->setSerializer(new JsonSerializer())
->parseIncludes(['stage', 'recordType']);
if ($this->request->has('leadId')) {
$leadId = $this->request->input('leadId');
try {
$lead = $this->getLead($leadId);
$response = $this->response->withItem($lead, new LeadTransformer());
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
} else {
$response = $this->response->withCollection($user->team->leads, new LeadTransformer());
}
return $response;
}
/**
* @param Request $request
*
* @throws ValidationException
*
* @return JsonResponse
*/
public function layouts(Request $request): JsonResponse
{
$request->validate([
'type' => 'required|in:' . implode(',', Layout::$enumTypes),
]);
$user = $request->user();
$type = $request->input('type');
// Take the activity type from the Playbook (default to first for orphaned users).
if ($user->group_id) {
$playbook = $user->group->playbook;
} else {
/** @var Playbook $playbook */
$playbook = $user->team->playbooks()->first();
}
if ($playbook === null) {
return $this->response->errorUnprocessable('Please configure a Playbook first.');
}
$layoutTypeParts = explode('-', $type);
$layoutType = sprintf(
'%s-%s',
reset($layoutTypeParts),
end($layoutTypeParts)
);
/** @var Layout|null $layout */
$layout = $playbook->layouts()
->where('name', ucfirst($playbook->activity_type) . ' Based Layout')
->where('type', $layoutType)
->first();
if ($layout === null) {
return $this->response->errorNotFound('Layout not found.');
}
$this->response
->getManager()
->setSerializer(new JsonSerializer())
->parseIncludes([
'entities.children.field.options',
]);
$transformer = new LayoutTransformer($user->crmProfile)
->setNoDefaultActivityTypeFollowUp(true)
;
return $this->response->withItem($layout, $transformer);
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmServiceWithActiveUser(User $user): ServiceInterface
{
if ($this->crmService === null) {
$team = $user->getTeam();
if (! $user->isCrmRequired()) {
$integrationAdmin = $team->getOwner();
} else {
$integrationAdmin = $user;
}
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $integrationAdmin,
'providerSlug' => $team->getCrmConfiguration()->getProviderName(),
]);
$this->crmService = $crmResolver->prepareCrmService();
}
return $this->crmService;
}
}...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09740692,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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.8374335,"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":"TextRelayServiceTest","depth":6,"bounds":{"left":0.85272604,"top":0.019952115,"width":0.062832445,"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 'TextRelayServiceTest'","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 'TextRelayServiceTest'","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":"48","depth":4,"bounds":{"left":0.375,"top":0.10055866,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"9","depth":4,"bounds":{"left":0.38730052,"top":0.10055866,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39694148,"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.40425533,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse DomainException;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\SalesforceInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\ServiceUnavailableException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\AccountTransformer;\nuse Jiminny\\Http\\Transformers\\ContactTransformer;\nuse Jiminny\\Http\\Transformers\\LayoutTransformer;\nuse Jiminny\\Http\\Transformers\\LeadTransformer;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass CrmController extends Controller\n{\n private const string MESSAGE_GENERAL_EXCEPTION_SEARCHING = 'Sorry, an internal error occurred whilst searching.';\n private const string MESSAGE_GENERAL_EXCEPTION = 'Sorry, an internal error occurred.';\n private ?ServiceInterface $crmService = null;\n\n public function __construct(Response $response)\n {\n parent::__construct($response);\n }\n\n /**\n * Method for searching for remote records by name.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function search(Request $request): mixed\n {\n $allowedScopes = [\n 'lead',\n 'account',\n 'contact',\n 'account-business',\n 'account-person',\n 'contact-business',\n 'contact-person',\n ];\n\n $request->validate([\n 'scopes' => 'required|in:' . implode(',', $allowedScopes) . '|array',\n 'name' => 'required|string|max:100|min:2',\n 'limit' => 'min:1|max:20',\n 'offset' => 'min:0',\n ]);\n\n $scopes = $request->input('scopes');\n $name = $request->input('name');\n $limit = $request->input('limit', 20);\n $offset = $request->input('offset', 0);\n $user = $this->getUserFromRequest($request);\n\n try {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n $crmService->setPage($limit, $offset);\n\n $response = $crmService->find($name, $scopes);\n } catch (SocialAccountTokenInvalidException $exception) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (CrmException $exception) {\n $response = [];\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return $response;\n }\n\n /**\n * Method for retrieving remote opportunities by account or contact.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function opportunities(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n\n try {\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],\n 'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],\n ]);\n\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($this->request->has('contactId')) {\n $contactId = $this->request->input('contactId');\n\n $contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();\n\n // Contact does not exist locally, import it.\n if ($contact === null) {\n $contact = $crmService->syncContact($contactId);\n }\n\n $accountId = $contact->account_id ? $contact->account->crm_provider_id : null;\n } else {\n $contactId = null;\n $accountId = $this->request->input('accountId');\n }\n\n $response = $crmService->findOpportunities($accountId, $contactId, $user->getId());\n } catch (\\InvalidArgumentException $exception) {\n $response = $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException $exception) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return $response;\n }\n\n /**\n * Method for retrieving remote tasks by user.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function activities(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'objectType' => 'in:lead,contact,account',\n 'prospectId' => new CrmReference($crmProvider),\n 'opportunityId' => new CrmReference($crmProvider),\n ]);\n\n try {\n $opportunityId = $request->input('opportunityId');\n $objectType = $request->input('objectType');\n $objectId = $request->input('prospectId');\n\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($objectType === null\n && $crmService instanceof SupportsObjectTypeParseInterface\n ) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n\n // Take the activity type from the Playbook (default to first for orphaned users).\n if ($user->group_id) {\n $playbook = $user->group->playbook;\n } else {\n $playbook = $user->team->playbooks()->first();\n\n // fix empty playbook\n if ($playbook === null) {\n throw new \\InvalidArgumentException('Please configure a Playbook first.');\n }\n }\n\n if ($crmService instanceof SalesforceInterface) {\n /**\n * Salesforce support Tasks and Events,\n * other crms support only Tasks\n */\n $activities = $playbook->activity_type === Playbook::ACTIVITY_TYPE_TASK\n ? $crmService->getTasks($objectType, $objectId, $opportunityId)\n : $crmService->getEvents($objectType, $objectId, $opportunityId);\n } else {\n $activities = $crmService->getTasks($objectType, $objectId, $opportunityId);\n }\n } catch (\\InvalidArgumentException $exception) {\n return $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException $exception) {\n return $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n return $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n\n return $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return [\n 'activities' => $activities,\n 'playbookActivityType' => $playbook->activity_type,\n ];\n }\n\n /**\n * Method for retrieving remote customer details.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function customers(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'objectType' => 'in:lead,contact,account,opportunity,undefined',\n 'providerId' => new CrmReference($crmProvider),\n 'phoneNumber' => 'phone:INTERNATIONAL,US,' . $user->country_code,\n ]);\n\n $objectType = $request->input('objectType');\n $objectId = $request->input('providerId');\n $phoneNumber = $request->input('phoneNumber');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n try {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($objectId) {\n if (($objectType === null || $objectType === 'undefined')\n && $crmService instanceof SupportsObjectTypeParseInterface\n ) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n\n switch ($objectType) {\n case 'lead':\n $lead = $this->getLead($objectId);\n $response = $this->response->withItem($lead, new LeadTransformer());\n\n break;\n\n case 'account':\n $account = $this->getAccount($objectId);\n $response = $this->response->withItem($account, new AccountTransformer());\n\n break;\n\n case 'contact':\n $contact = $this->getContact($objectId);\n $response = $this->response->withItem($contact, new ContactTransformer());\n\n break;\n\n case 'opportunity':\n $opportunity = $this->getOpportunity($objectId);\n $response = $this->response->withItem($opportunity->account, new AccountTransformer());\n\n break;\n\n default:\n $response = $this->response->errorWrongArgs('Sorry, we don\\'t support messaging this type of record.');\n\n break;\n }\n } elseif ($phoneNumber) {\n [$lead, $account, , $contact] = $crmService->matchByPhone(\n $phoneNumber,\n null,\n $user->getId()\n );\n\n if ($lead) {\n $response = $this->response->withItem($lead, new LeadTransformer());\n } elseif ($account) {\n $response = $this->response->withItem($account, new AccountTransformer());\n } elseif ($contact) {\n $response = $this->response->withItem($contact, new ContactTransformer());\n } else {\n $response = $this->response->errorNotFound('Customer not found.');\n }\n } else {\n $response = $this->response->errorWrongArgs('No search data provided.');\n }\n } catch (\\InvalidArgumentException $exception) {\n $response = $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION);\n }\n\n return $response;\n }\n\n /**\n * Rest method for retrieving accounts.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function accounts(): mixed\n {\n $user = $this->getUserFromRequest($this->request);\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'accountId' => new CrmReference($crmProvider),\n ]);\n\n $this->response->getManager()->setSerializer(new JsonSerializer());\n\n if ($this->request->has('accountId')) {\n $accountId = $this->request->input('accountId');\n\n try {\n $account = $this->getAccount($accountId);\n\n $response = $this->response->withItem($account, new AccountTransformer());\n } catch (DomainException) {\n $response = $this->response->errorNotFound('Record not found.');\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n } else {\n $response = $this->response->withCollection($user->team->accounts, new AccountTransformer());\n }\n\n return $response;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $accountId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return Account\n */\n private function getAccount(string $accountId): Account\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountId)->first();\n\n if ($account instanceof Account) {\n return $account;\n }\n\n // Account does not exist locally, import it.\n try {\n return $this->getCrmServiceWithActiveUser($user)->syncAccount($accountId);\n } catch (SocialAccountTokenInvalidException $exception) {\n return $this->response->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.'\n );\n }\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $opportunityId\n *\n * @throws DomainException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Opportunity\n */\n private function getOpportunity(string $opportunityId): Opportunity\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if (! $opportunity instanceof Opportunity) {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n // Sanity check.\n if ($user->team_id !== $opportunity->account->team_id) {\n throw new DomainException('Opportunity not found.');\n }\n\n return $opportunity;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $contactId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Contact\n */\n private function getContact(string $contactId): Contact\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n $contact = $crmService->syncContact($contactId);\n }\n\n return $contact;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $leadId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Lead\n */\n private function getLead(string $leadId): Lead\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $lead = $team->crm->leads()->where('crm_provider_id', $leadId)->first();\n\n if ($lead instanceof Lead) {\n return $lead;\n }\n\n // Lead does not exist locally, import it.\n return $this->getCrmServiceWithActiveUser($user)->syncLead($leadId);\n }\n\n /**\n * Rest method for retrieving contacts.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function contacts(): mixed\n {\n $user = $this->request->user();\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],\n 'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n try {\n // Determine if they wish to retrieve a single contact or multiple for an account.\n if ($this->request->has('contactId')) {\n $contactId = $this->request->input('contactId');\n $contact = $this->getContact($contactId);\n\n $response = $this->response->withItem($contact, new ContactTransformer());\n } else {\n $accountId = $this->request->input('accountId');\n $account = $this->getAccount($accountId);\n\n $response = $this->response->withCollection($account->contacts, new ContactTransformer());\n }\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n\n return $response;\n }\n\n /**\n * Rest method for retrieving leads.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function leads(): mixed\n {\n $user = $this->request->user();\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'leadId' => new CrmReference($crmProvider),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer())\n ->parseIncludes(['stage', 'recordType']);\n\n if ($this->request->has('leadId')) {\n $leadId = $this->request->input('leadId');\n\n try {\n $lead = $this->getLead($leadId);\n\n $response = $this->response->withItem($lead, new LeadTransformer());\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n } else {\n $response = $this->response->withCollection($user->team->leads, new LeadTransformer());\n }\n\n return $response;\n }\n\n /**\n * @param Request $request\n *\n * @throws ValidationException\n *\n * @return JsonResponse\n */\n public function layouts(Request $request): JsonResponse\n {\n $request->validate([\n 'type' => 'required|in:' . implode(',', Layout::$enumTypes),\n ]);\n\n $user = $request->user();\n $type = $request->input('type');\n\n // Take the activity type from the Playbook (default to first for orphaned users).\n if ($user->group_id) {\n $playbook = $user->group->playbook;\n } else {\n /** @var Playbook $playbook */\n $playbook = $user->team->playbooks()->first();\n }\n\n if ($playbook === null) {\n return $this->response->errorUnprocessable('Please configure a Playbook first.');\n }\n\n $layoutTypeParts = explode('-', $type);\n\n $layoutType = sprintf(\n '%s-%s',\n reset($layoutTypeParts),\n end($layoutTypeParts)\n );\n\n /** @var Layout|null $layout */\n $layout = $playbook->layouts()\n ->where('name', ucfirst($playbook->activity_type) . ' Based Layout')\n ->where('type', $layoutType)\n ->first();\n\n if ($layout === null) {\n return $this->response->errorNotFound('Layout not found.');\n }\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer())\n ->parseIncludes([\n 'entities.children.field.options',\n ]);\n\n $transformer = new LayoutTransformer($user->crmProfile)\n ->setNoDefaultActivityTypeFollowUp(true)\n ;\n\n return $this->response->withItem($layout, $transformer);\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmServiceWithActiveUser(User $user): ServiceInterface\n {\n if ($this->crmService === null) {\n $team = $user->getTeam();\n\n if (! $user->isCrmRequired()) {\n $integrationAdmin = $team->getOwner();\n } else {\n $integrationAdmin = $user;\n }\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $integrationAdmin,\n 'providerSlug' => $team->getCrmConfiguration()->getProviderName(),\n ]);\n\n $this->crmService = $crmResolver->prepareCrmService();\n }\n\n return $this->crmService;\n }\n}","depth":4,"bounds":{"left":0.13630319,"top":0.09736632,"width":0.31083778,"height":0.90263367},"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse DomainException;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\SalesforceInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\ServiceUnavailableException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\AccountTransformer;\nuse Jiminny\\Http\\Transformers\\ContactTransformer;\nuse Jiminny\\Http\\Transformers\\LayoutTransformer;\nuse Jiminny\\Http\\Transformers\\LeadTransformer;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass CrmController extends Controller\n{\n private const string MESSAGE_GENERAL_EXCEPTION_SEARCHING = 'Sorry, an internal error occurred whilst searching.';\n private const string MESSAGE_GENERAL_EXCEPTION = 'Sorry, an internal error occurred.';\n private ?ServiceInterface $crmService = null;\n\n public function __construct(Response $response)\n {\n parent::__construct($response);\n }\n\n /**\n * Method for searching for remote records by name.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function search(Request $request): mixed\n {\n $allowedScopes = [\n 'lead',\n 'account',\n 'contact',\n 'account-business',\n 'account-person',\n 'contact-business',\n 'contact-person',\n ];\n\n $request->validate([\n 'scopes' => 'required|in:' . implode(',', $allowedScopes) . '|array',\n 'name' => 'required|string|max:100|min:2',\n 'limit' => 'min:1|max:20',\n 'offset' => 'min:0',\n ]);\n\n $scopes = $request->input('scopes');\n $name = $request->input('name');\n $limit = $request->input('limit', 20);\n $offset = $request->input('offset', 0);\n $user = $this->getUserFromRequest($request);\n\n try {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n $crmService->setPage($limit, $offset);\n\n $response = $crmService->find($name, $scopes);\n } catch (SocialAccountTokenInvalidException $exception) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (CrmException $exception) {\n $response = [];\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return $response;\n }\n\n /**\n * Method for retrieving remote opportunities by account or contact.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function opportunities(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n\n try {\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],\n 'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],\n ]);\n\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($this->request->has('contactId')) {\n $contactId = $this->request->input('contactId');\n\n $contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();\n\n // Contact does not exist locally, import it.\n if ($contact === null) {\n $contact = $crmService->syncContact($contactId);\n }\n\n $accountId = $contact->account_id ? $contact->account->crm_provider_id : null;\n } else {\n $contactId = null;\n $accountId = $this->request->input('accountId');\n }\n\n $response = $crmService->findOpportunities($accountId, $contactId, $user->getId());\n } catch (\\InvalidArgumentException $exception) {\n $response = $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException $exception) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return $response;\n }\n\n /**\n * Method for retrieving remote tasks by user.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function activities(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'objectType' => 'in:lead,contact,account',\n 'prospectId' => new CrmReference($crmProvider),\n 'opportunityId' => new CrmReference($crmProvider),\n ]);\n\n try {\n $opportunityId = $request->input('opportunityId');\n $objectType = $request->input('objectType');\n $objectId = $request->input('prospectId');\n\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($objectType === null\n && $crmService instanceof SupportsObjectTypeParseInterface\n ) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n\n // Take the activity type from the Playbook (default to first for orphaned users).\n if ($user->group_id) {\n $playbook = $user->group->playbook;\n } else {\n $playbook = $user->team->playbooks()->first();\n\n // fix empty playbook\n if ($playbook === null) {\n throw new \\InvalidArgumentException('Please configure a Playbook first.');\n }\n }\n\n if ($crmService instanceof SalesforceInterface) {\n /**\n * Salesforce support Tasks and Events,\n * other crms support only Tasks\n */\n $activities = $playbook->activity_type === Playbook::ACTIVITY_TYPE_TASK\n ? $crmService->getTasks($objectType, $objectId, $opportunityId)\n : $crmService->getEvents($objectType, $objectId, $opportunityId);\n } else {\n $activities = $crmService->getTasks($objectType, $objectId, $opportunityId);\n }\n } catch (\\InvalidArgumentException $exception) {\n return $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException $exception) {\n return $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n return $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n\n return $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);\n }\n\n return [\n 'activities' => $activities,\n 'playbookActivityType' => $playbook->activity_type,\n ];\n }\n\n /**\n * Method for retrieving remote customer details.\n *\n * @param Request $request\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return mixed\n */\n public function customers(Request $request): mixed\n {\n $user = $this->getUserFromRequest($request);\n $team = $user->getTeam();\n $crmProvider = $team->crm->provider;\n\n $request->validate([\n 'objectType' => 'in:lead,contact,account,opportunity,undefined',\n 'providerId' => new CrmReference($crmProvider),\n 'phoneNumber' => 'phone:INTERNATIONAL,US,' . $user->country_code,\n ]);\n\n $objectType = $request->input('objectType');\n $objectId = $request->input('providerId');\n $phoneNumber = $request->input('phoneNumber');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n try {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n if ($objectId) {\n if (($objectType === null || $objectType === 'undefined')\n && $crmService instanceof SupportsObjectTypeParseInterface\n ) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n\n switch ($objectType) {\n case 'lead':\n $lead = $this->getLead($objectId);\n $response = $this->response->withItem($lead, new LeadTransformer());\n\n break;\n\n case 'account':\n $account = $this->getAccount($objectId);\n $response = $this->response->withItem($account, new AccountTransformer());\n\n break;\n\n case 'contact':\n $contact = $this->getContact($objectId);\n $response = $this->response->withItem($contact, new ContactTransformer());\n\n break;\n\n case 'opportunity':\n $opportunity = $this->getOpportunity($objectId);\n $response = $this->response->withItem($opportunity->account, new AccountTransformer());\n\n break;\n\n default:\n $response = $this->response->errorWrongArgs('Sorry, we don\\'t support messaging this type of record.');\n\n break;\n }\n } elseif ($phoneNumber) {\n [$lead, $account, , $contact] = $crmService->matchByPhone(\n $phoneNumber,\n null,\n $user->getId()\n );\n\n if ($lead) {\n $response = $this->response->withItem($lead, new LeadTransformer());\n } elseif ($account) {\n $response = $this->response->withItem($account, new AccountTransformer());\n } elseif ($contact) {\n $response = $this->response->withItem($contact, new ContactTransformer());\n } else {\n $response = $this->response->errorNotFound('Customer not found.');\n }\n } else {\n $response = $this->response->errorWrongArgs('No search data provided.');\n }\n } catch (\\InvalidArgumentException $exception) {\n $response = $this->response->errorUnprocessable($exception->getMessage());\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n } catch (\\Exception $exception) {\n \\Sentry::captureException($exception);\n $response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION);\n }\n\n return $response;\n }\n\n /**\n * Rest method for retrieving accounts.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function accounts(): mixed\n {\n $user = $this->getUserFromRequest($this->request);\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'accountId' => new CrmReference($crmProvider),\n ]);\n\n $this->response->getManager()->setSerializer(new JsonSerializer());\n\n if ($this->request->has('accountId')) {\n $accountId = $this->request->input('accountId');\n\n try {\n $account = $this->getAccount($accountId);\n\n $response = $this->response->withItem($account, new AccountTransformer());\n } catch (DomainException) {\n $response = $this->response->errorNotFound('Record not found.');\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n } else {\n $response = $this->response->withCollection($user->team->accounts, new AccountTransformer());\n }\n\n return $response;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $accountId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n *\n * @return Account\n */\n private function getAccount(string $accountId): Account\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountId)->first();\n\n if ($account instanceof Account) {\n return $account;\n }\n\n // Account does not exist locally, import it.\n try {\n return $this->getCrmServiceWithActiveUser($user)->syncAccount($accountId);\n } catch (SocialAccountTokenInvalidException $exception) {\n return $this->response->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.'\n );\n }\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $opportunityId\n *\n * @throws DomainException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Opportunity\n */\n private function getOpportunity(string $opportunityId): Opportunity\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if (! $opportunity instanceof Opportunity) {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n // Sanity check.\n if ($user->team_id !== $opportunity->account->team_id) {\n throw new DomainException('Opportunity not found.');\n }\n\n return $opportunity;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $contactId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Contact\n */\n private function getContact(string $contactId): Contact\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $crmService = $this->getCrmServiceWithActiveUser($user);\n\n $contact = $crmService->syncContact($contactId);\n }\n\n return $contact;\n }\n\n /**\n * Todo: Move to a repository with the CRM transparently importing the record.\n *\n * @param string $leadId\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n *\n * @return Lead\n */\n private function getLead(string $leadId): Lead\n {\n $user = $this->getUserFromRequest($this->request);\n $team = $user->getTeam();\n\n $lead = $team->crm->leads()->where('crm_provider_id', $leadId)->first();\n\n if ($lead instanceof Lead) {\n return $lead;\n }\n\n // Lead does not exist locally, import it.\n return $this->getCrmServiceWithActiveUser($user)->syncLead($leadId);\n }\n\n /**\n * Rest method for retrieving contacts.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function contacts(): mixed\n {\n $user = $this->request->user();\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],\n 'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n try {\n // Determine if they wish to retrieve a single contact or multiple for an account.\n if ($this->request->has('contactId')) {\n $contactId = $this->request->input('contactId');\n $contact = $this->getContact($contactId);\n\n $response = $this->response->withItem($contact, new ContactTransformer());\n } else {\n $accountId = $this->request->input('accountId');\n $account = $this->getAccount($accountId);\n\n $response = $this->response->withCollection($account->contacts, new ContactTransformer());\n }\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n\n return $response;\n }\n\n /**\n * Rest method for retrieving leads.\n *\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws ValidationException\n *\n * @return mixed\n */\n public function leads(): mixed\n {\n $user = $this->request->user();\n $crmProvider = $user->team->crm->provider;\n\n $this->request->validate([\n 'leadId' => new CrmReference($crmProvider),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer())\n ->parseIncludes(['stage', 'recordType']);\n\n if ($this->request->has('leadId')) {\n $leadId = $this->request->input('leadId');\n\n try {\n $lead = $this->getLead($leadId);\n\n $response = $this->response->withItem($lead, new LeadTransformer());\n } catch (SocialAccountTokenInvalidException) {\n $response = $this->response\n ->errorForbidden(\n 'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',\n );\n } catch (ServiceUnavailableException $exception) {\n $response = $this->response->errorServiceUnavailable($exception->getMessage());\n }\n } else {\n $response = $this->response->withCollection($user->team->leads, new LeadTransformer());\n }\n\n return $response;\n }\n\n /**\n * @param Request $request\n *\n * @throws ValidationException\n *\n * @return JsonResponse\n */\n public function layouts(Request $request): JsonResponse\n {\n $request->validate([\n 'type' => 'required|in:' . implode(',', Layout::$enumTypes),\n ]);\n\n $user = $request->user();\n $type = $request->input('type');\n\n // Take the activity type from the Playbook (default to first for orphaned users).\n if ($user->group_id) {\n $playbook = $user->group->playbook;\n } else {\n /** @var Playbook $playbook */\n $playbook = $user->team->playbooks()->first();\n }\n\n if ($playbook === null) {\n return $this->response->errorUnprocessable('Please configure a Playbook first.');\n }\n\n $layoutTypeParts = explode('-', $type);\n\n $layoutType = sprintf(\n '%s-%s',\n reset($layoutTypeParts),\n end($layoutTypeParts)\n );\n\n /** @var Layout|null $layout */\n $layout = $playbook->layouts()\n ->where('name', ucfirst($playbook->activity_type) . ' Based Layout')\n ->where('type', $layoutType)\n ->first();\n\n if ($layout === null) {\n return $this->response->errorNotFound('Layout not found.');\n }\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer())\n ->parseIncludes([\n 'entities.children.field.options',\n ]);\n\n $transformer = new LayoutTransformer($user->crmProfile)\n ->setNoDefaultActivityTypeFollowUp(true)\n ;\n\n return $this->response->withItem($layout, $transformer);\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmServiceWithActiveUser(User $user): ServiceInterface\n {\n if ($this->crmService === null) {\n $team = $user->getTeam();\n\n if (! $user->isCrmRequired()) {\n $integrationAdmin = $team->getOwner();\n } else {\n $integrationAdmin = $user;\n }\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $integrationAdmin,\n 'providerSlug' => $team->getCrmConfiguration()->getProviderName(),\n ]);\n\n $this->crmService = $crmResolver->prepareCrmService();\n }\n\n return $this->crmService;\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false}]...
|
-7659978220986430141
|
-3752135871855184809
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
48
9
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use DomainException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Jiminny\Contracts\Services\Crm\Provider\SalesforceInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\ServiceUnavailableException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\AccountTransformer;
use Jiminny\Http\Transformers\ContactTransformer;
use Jiminny\Http\Transformers\LayoutTransformer;
use Jiminny\Http\Transformers\LeadTransformer;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Models\Account;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Playbook;
use Jiminny\Models\User;
use Jiminny\Rules\CrmReference;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class CrmController extends Controller
{
private const string MESSAGE_GENERAL_EXCEPTION_SEARCHING = 'Sorry, an internal error occurred whilst searching.';
private const string MESSAGE_GENERAL_EXCEPTION = 'Sorry, an internal error occurred.';
private ?ServiceInterface $crmService = null;
public function __construct(Response $response)
{
parent::__construct($response);
}
/**
* Method for searching for remote records by name.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function search(Request $request): mixed
{
$allowedScopes = [
'lead',
'account',
'contact',
'account-business',
'account-person',
'contact-business',
'contact-person',
];
$request->validate([
'scopes' => 'required|in:' . implode(',', $allowedScopes) . '|array',
'name' => 'required|string|max:100|min:2',
'limit' => 'min:1|max:20',
'offset' => 'min:0',
]);
$scopes = $request->input('scopes');
$name = $request->input('name');
$limit = $request->input('limit', 20);
$offset = $request->input('offset', 0);
$user = $this->getUserFromRequest($request);
try {
$crmService = $this->getCrmServiceWithActiveUser($user);
$crmService->setPage($limit, $offset);
$response = $crmService->find($name, $scopes);
} catch (SocialAccountTokenInvalidException $exception) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (CrmException $exception) {
$response = [];
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return $response;
}
/**
* Method for retrieving remote opportunities by account or contact.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function opportunities(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
try {
$crmProvider = $team->crm->provider;
$request->validate([
'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],
'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],
]);
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($this->request->has('contactId')) {
$contactId = $this->request->input('contactId');
$contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();
// Contact does not exist locally, import it.
if ($contact === null) {
$contact = $crmService->syncContact($contactId);
}
$accountId = $contact->account_id ? $contact->account->crm_provider_id : null;
} else {
$contactId = null;
$accountId = $this->request->input('accountId');
}
$response = $crmService->findOpportunities($accountId, $contactId, $user->getId());
} catch (\InvalidArgumentException $exception) {
$response = $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException $exception) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return $response;
}
/**
* Method for retrieving remote tasks by user.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function activities(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
$crmProvider = $team->crm->provider;
$request->validate([
'objectType' => 'in:lead,contact,account',
'prospectId' => new CrmReference($crmProvider),
'opportunityId' => new CrmReference($crmProvider),
]);
try {
$opportunityId = $request->input('opportunityId');
$objectType = $request->input('objectType');
$objectId = $request->input('prospectId');
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($objectType === null
&& $crmService instanceof SupportsObjectTypeParseInterface
) {
$objectType = $crmService->parseObjectType($objectId);
}
// Take the activity type from the Playbook (default to first for orphaned users).
if ($user->group_id) {
$playbook = $user->group->playbook;
} else {
$playbook = $user->team->playbooks()->first();
// fix empty playbook
if ($playbook === null) {
throw new \InvalidArgumentException('Please configure a Playbook first.');
}
}
if ($crmService instanceof SalesforceInterface) {
/**
* Salesforce support Tasks and Events,
* other crms support only Tasks
*/
$activities = $playbook->activity_type === Playbook::ACTIVITY_TYPE_TASK
? $crmService->getTasks($objectType, $objectId, $opportunityId)
: $crmService->getEvents($objectType, $objectId, $opportunityId);
} else {
$activities = $crmService->getTasks($objectType, $objectId, $opportunityId);
}
} catch (\InvalidArgumentException $exception) {
return $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException $exception) {
return $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
return $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
return $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION_SEARCHING);
}
return [
'activities' => $activities,
'playbookActivityType' => $playbook->activity_type,
];
}
/**
* Method for retrieving remote customer details.
*
* @param Request $request
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return mixed
*/
public function customers(Request $request): mixed
{
$user = $this->getUserFromRequest($request);
$team = $user->getTeam();
$crmProvider = $team->crm->provider;
$request->validate([
'objectType' => 'in:lead,contact,account,opportunity,undefined',
'providerId' => new CrmReference($crmProvider),
'phoneNumber' => 'phone:INTERNATIONAL,US,' . $user->country_code,
]);
$objectType = $request->input('objectType');
$objectId = $request->input('providerId');
$phoneNumber = $request->input('phoneNumber');
$this->response
->getManager()
->setSerializer(new JsonSerializer());
try {
$crmService = $this->getCrmServiceWithActiveUser($user);
if ($objectId) {
if (($objectType === null || $objectType === 'undefined')
&& $crmService instanceof SupportsObjectTypeParseInterface
) {
$objectType = $crmService->parseObjectType($objectId);
}
switch ($objectType) {
case 'lead':
$lead = $this->getLead($objectId);
$response = $this->response->withItem($lead, new LeadTransformer());
break;
case 'account':
$account = $this->getAccount($objectId);
$response = $this->response->withItem($account, new AccountTransformer());
break;
case 'contact':
$contact = $this->getContact($objectId);
$response = $this->response->withItem($contact, new ContactTransformer());
break;
case 'opportunity':
$opportunity = $this->getOpportunity($objectId);
$response = $this->response->withItem($opportunity->account, new AccountTransformer());
break;
default:
$response = $this->response->errorWrongArgs('Sorry, we don\'t support messaging this type of record.');
break;
}
} elseif ($phoneNumber) {
[$lead, $account, , $contact] = $crmService->matchByPhone(
$phoneNumber,
null,
$user->getId()
);
if ($lead) {
$response = $this->response->withItem($lead, new LeadTransformer());
} elseif ($account) {
$response = $this->response->withItem($account, new AccountTransformer());
} elseif ($contact) {
$response = $this->response->withItem($contact, new ContactTransformer());
} else {
$response = $this->response->errorNotFound('Customer not found.');
}
} else {
$response = $this->response->errorWrongArgs('No search data provided.');
}
} catch (\InvalidArgumentException $exception) {
$response = $this->response->errorUnprocessable($exception->getMessage());
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
} catch (\Exception $exception) {
\Sentry::captureException($exception);
$response = $this->response->errorInternalError(self::MESSAGE_GENERAL_EXCEPTION);
}
return $response;
}
/**
* Rest method for retrieving accounts.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function accounts(): mixed
{
$user = $this->getUserFromRequest($this->request);
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'accountId' => new CrmReference($crmProvider),
]);
$this->response->getManager()->setSerializer(new JsonSerializer());
if ($this->request->has('accountId')) {
$accountId = $this->request->input('accountId');
try {
$account = $this->getAccount($accountId);
$response = $this->response->withItem($account, new AccountTransformer());
} catch (DomainException) {
$response = $this->response->errorNotFound('Record not found.');
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
} else {
$response = $this->response->withCollection($user->team->accounts, new AccountTransformer());
}
return $response;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $accountId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*
* @return Account
*/
private function getAccount(string $accountId): Account
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$account = $team->crm->accounts()->where('crm_provider_id', $accountId)->first();
if ($account instanceof Account) {
return $account;
}
// Account does not exist locally, import it.
try {
return $this->getCrmServiceWithActiveUser($user)->syncAccount($accountId);
} catch (SocialAccountTokenInvalidException $exception) {
return $this->response->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.'
);
}
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $opportunityId
*
* @throws DomainException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Opportunity
*/
private function getOpportunity(string $opportunityId): Opportunity
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if (! $opportunity instanceof Opportunity) {
$crmService = $this->getCrmServiceWithActiveUser($user);
$opportunity = $crmService->syncOpportunity($opportunityId);
}
// Sanity check.
if ($user->team_id !== $opportunity->account->team_id) {
throw new DomainException('Opportunity not found.');
}
return $opportunity;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $contactId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Contact
*/
private function getContact(string $contactId): Contact
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$contact = $team->crm->contacts()->where('crm_provider_id', $contactId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$crmService = $this->getCrmServiceWithActiveUser($user);
$contact = $crmService->syncContact($contactId);
}
return $contact;
}
/**
* Todo: Move to a repository with the CRM transparently importing the record.
*
* @param string $leadId
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*
* @return Lead
*/
private function getLead(string $leadId): Lead
{
$user = $this->getUserFromRequest($this->request);
$team = $user->getTeam();
$lead = $team->crm->leads()->where('crm_provider_id', $leadId)->first();
if ($lead instanceof Lead) {
return $lead;
}
// Lead does not exist locally, import it.
return $this->getCrmServiceWithActiveUser($user)->syncLead($leadId);
}
/**
* Rest method for retrieving contacts.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function contacts(): mixed
{
$user = $this->request->user();
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'accountId' => ['required_without:contactId', new CrmReference($crmProvider)],
'contactId' => ['required_without:accountId', new CrmReference($crmProvider)],
]);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
try {
// Determine if they wish to retrieve a single contact or multiple for an account.
if ($this->request->has('contactId')) {
$contactId = $this->request->input('contactId');
$contact = $this->getContact($contactId);
$response = $this->response->withItem($contact, new ContactTransformer());
} else {
$accountId = $this->request->input('accountId');
$account = $this->getAccount($accountId);
$response = $this->response->withCollection($account->contacts, new ContactTransformer());
}
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
return $response;
}
/**
* Rest method for retrieving leads.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ValidationException
*
* @return mixed
*/
public function leads(): mixed
{
$user = $this->request->user();
$crmProvider = $user->team->crm->provider;
$this->request->validate([
'leadId' => new CrmReference($crmProvider),
]);
$this->response
->getManager()
->setSerializer(new JsonSerializer())
->parseIncludes(['stage', 'recordType']);
if ($this->request->has('leadId')) {
$leadId = $this->request->input('leadId');
try {
$lead = $this->getLead($leadId);
$response = $this->response->withItem($lead, new LeadTransformer());
} catch (SocialAccountTokenInvalidException) {
$response = $this->response
->errorForbidden(
'Sorry, your CRM connection has expired. Please visit Jiminny to re-connect and try again.',
);
} catch (ServiceUnavailableException $exception) {
$response = $this->response->errorServiceUnavailable($exception->getMessage());
}
} else {
$response = $this->response->withCollection($user->team->leads, new LeadTransformer());
}
return $response;
}
/**
* @param Request $request
*
* @throws ValidationException
*
* @return JsonResponse
*/
public function layouts(Request $request): JsonResponse
{
$request->validate([
'type' => 'required|in:' . implode(',', Layout::$enumTypes),
]);
$user = $request->user();
$type = $request->input('type');
// Take the activity type from the Playbook (default to first for orphaned users).
if ($user->group_id) {
$playbook = $user->group->playbook;
} else {
/** @var Playbook $playbook */
$playbook = $user->team->playbooks()->first();
}
if ($playbook === null) {
return $this->response->errorUnprocessable('Please configure a Playbook first.');
}
$layoutTypeParts = explode('-', $type);
$layoutType = sprintf(
'%s-%s',
reset($layoutTypeParts),
end($layoutTypeParts)
);
/** @var Layout|null $layout */
$layout = $playbook->layouts()
->where('name', ucfirst($playbook->activity_type) . ' Based Layout')
->where('type', $layoutType)
->first();
if ($layout === null) {
return $this->response->errorNotFound('Layout not found.');
}
$this->response
->getManager()
->setSerializer(new JsonSerializer())
->parseIncludes([
'entities.children.field.options',
]);
$transformer = new LayoutTransformer($user->crmProfile)
->setNoDefaultActivityTypeFollowUp(true)
;
return $this->response->withItem($layout, $transformer);
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmServiceWithActiveUser(User $user): ServiceInterface
{
if ($this->crmService === null) {
$team = $user->getTeam();
if (! $user->isCrmRequired()) {
$integrationAdmin = $team->getOwner();
} else {
$integrationAdmin = $user;
}
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $integrationAdmin,
'providerSlug' => $team->getCrmConfiguration()->getProviderName(),
]);
$this->crmService = $crmResolver->prepareCrmService();
}
return $this->crmService;
}
}...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79495
|
2787
|
53
|
2026-05-28T06:31:50.611712+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949910611_m2.jpg...
|
PhpStorm
|
faVsco.js – api.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormEV faVsco,ls ~Projectvpto connect-provider PhpStormEV faVsco,ls ~Projectvpto connect-providers.phpphe cors.phppho database.ohopho datadog-helper.phppho debugbar.phppho emails-Import-filters.phppho es-mapping-settings.phppo ffmpeg.phpmiesysiems.onomo fractal,phpwo hashids.phpmo hashing.phpwpide-helper.ohgmo image.phpViewCoot%0tv-mnotC.themieein.hasdor.torterolasRurToolsWindowphpliminny.ohpphplang.ohopho maillonopho men.nhopho medaastreamina.oodpho manhe calonopto queue.phppho salastorce.obdpho samip obdnho sacure-headers obdpte sentry.phpMo sarvicas nhrme session.phpmo slack.phpmo testing-phpmotimezones.phpmoview.phppe webhook-server.php• E contrib› E docs>Ea front-end> M land› E node_modules library root› E phpstan> public> En rescurcesv Oroutespho aninhnpte apL_v2,phpnho console.nhoKeroaioh.© SyneMailbox.php© TextRelayServiceTest.phppto jiminny.phpx 3 Ccpho api.php *555ба declare(strict_types=1);* API routes.* Bsee |Jininny\Providers|RouteServiceProvider* Byac Router Srouter› use ...// ncp.audit MUST stay outernost so its Snext(Srequest) call wraps the auth// and tier guards. Otherwise 401 (auth:api) and 483 (ncp.tier) rejections// short-circuit before McpAuditMiddLeware::handle ever runs and we lose// audit rows for exactly the requests the security log most needs to capture.// McpAuditMiddleware: :writeAuditRow null-checks Srequest-›user(), so writing// pre-auth is safe.Ncp::web( route:) "/mcp', (serverClass: JininnyServer::class)->niddLewareC['ncp.audit'.› Srouter-›group(('middtenare' => ['auth:api']l, static function (Router Srouter): void (...}):> Srouter->orouodlmiddlemare" e>authrao statie functaion(Router Srouter): void (...h):› Srouter-›group(( 'middlemare' => ['apt'Il, static function(Router Srouter): void (...J):7262› Srouter->group(['prefix' »> 'user'], static function (Router Srouter): void (....):- 263› Srouter->group([ 'middleware' => ['auth:api']."profix' →) gas'), statle funetion (Router Srouter): vo1a_ ,55› Srouter-›group(['middleware' => ['auth:aps']), static function (Router Srouter): void (...}):=257Srouter->group(['prefix' => 'page", 'niddlemare' => ['api', 'auth:api')), static function () use (SrouteE 269)› Srouter-group(l'prefix" => "partners", 'aiddlenare' => 'auth:partner-api"), static funetion () use (5roU 271› Srouter-group(['prefix' → 'activity", 'nidatenare' => 'api"), statie funetion () use (Srouter): void ( 273274› Srouter->group(['middleware' => ['auth:api']], static function () use (Srouter) (...}):=273•Srouter-›group(['middlenare' => ['auth:api']l, static function (Router Srouter): void (...}):=['prefix' => "/opportunity/{opportunity}''niddlenare' => ['api']].static function (Router Srouter): void (...).laravellogSF jiminny@localhost] x 4 HSJocal ([iminny@localhost)A console [PROD]A console (EU]A console (STAGING)TcAutoyDo jminnyihacriwitiesaDiusers u. nc-l: On aruser o = u.dUaGlBlYzYoa.status = 'completed"ANo uurd to bind 64f1ac0-1608-4201-8726-0757979da08eeu.uusdAND a.deleted_at IS NULLANDSXTESSELECT 1 FROM tracks tWHERE t.activity_id = a.idAND t.type IN ('audio', "video')EDER BY a.actual_start,time DESCilect * fron teans where id = 19:ilect * fron crn_configurations where provider = 'Ripedcive':CONCAT(u.id, CASE WHEN U.id = t.ouner_id THEN • (onner)' ELSE ** END) AS user_id,UrehazlSa.xt.ouner_id FROM social_accounts sawusers uon urs sansodaolenIIN teans t 1.n<->1: on t.id = u.team_idJERE u,tean 1d = 19 and sa,onoyiden = "oipedoive':*Kun sooaaecounsnmekenoeaalonDATe sochal accounts set onoviden usen token = "Mu:ADCA:--21 K2yuuuaLos2hwo9crunklok4el09cinXoo dAEchohdoVasnyichEynoysovider_refresh_token = ^5034113:195S5731:87c14258f8c813d02767ee975f6844846b6b2bfc',oines = 998919941ERE 1031516provider_user-token": "viu:AQLBAH5-L2/NK2yuuuaLqifzh#b9crUNKtpk4F109minXap_6AE0hDhD0Va1nviCHEvnpvSEAAAAf:1888gkqhk169w8BBwgg"provider refresh_token": "5834113:[TELEGRAM_TOKEN]b2bfc*Montton on old walmoc.ilect * fron crn_fields where type = 'nulti-picklist';ELECT * FROM crn_Layouts WHERE uuid_to_bin('7C327871-fc25-4056-9a0f-44c5a849d65c') = uuid;ELECT * FROM crm layout entities WHERE crn layout id = 282:ELECT * FROM crn_fields WHERE id = 3014; # 1885ELECT * FROM crn_field_vatues WHERE crn_field_id = 3014;00%LXThu 28 May 9:31:50U TextRelayServiceTest~aer henseict+0.can I test it locally first. if I place env from stagingYes. The service relies on a few things you'd need in place:1. Credentials file The constructor expects storage/text-relay.json (a Google service account JSON key file)Gmbtrom sthaind and oince it there2. .env values to copy from stagingGOOGLE TEXTUSERECOOGLE TEXTI HASTGOOGLE_TEXT_RELAY_TOPIC=DEPLOY _REGION=the cnail mailbox address# e.g. txt.jiminny.com or txt.staging.jiminny.com# the Pub/Sub topie name* eu or us3. Run the sync manually via tinker (inside docker_lanp_1):D bashdocker exec -it docker_lamp_1 php artisan tinker• 0app(\Jininny\ServicesVMail\TextRelayServices:class)->sync();Caveat: The service reads from Gmail history and dispatches jobs to the queue. If you don't want it to actuallsend SMS, make sure QUEUE_CONNECTION-syne is not set (cr use a test queue), or just call isForCurrentEnvironmtioh.Ssvc = new class extends \JiminnylServicesVa1l\TextRelayService ( public function _constructlSom Service ssvc-soctServicelcont.aasI then sinsoect a eessade canual1sasg = SgnaitService-susers_gessages-sget(config(*Jiainny-9009le_text_user*), "THE_MESSAGE_ID*)collect (Sasg->getPayload()-»getHeaders())->pluck("value',thut wey von can Mrity what handare tra nehhilm oraesot do ttat macesos alote tha ull evoc muneAsk anything (Xol- @ eodeAdhotvtModereimeelcharies2 4 space:...
|
NULL
|
-7245515244461660542
|
NULL
|
typing_pause
|
ocr
|
NULL
|
PhpStormEV faVsco,ls ~Projectvpto connect-provider PhpStormEV faVsco,ls ~Projectvpto connect-providers.phpphe cors.phppho database.ohopho datadog-helper.phppho debugbar.phppho emails-Import-filters.phppho es-mapping-settings.phppo ffmpeg.phpmiesysiems.onomo fractal,phpwo hashids.phpmo hashing.phpwpide-helper.ohgmo image.phpViewCoot%0tv-mnotC.themieein.hasdor.torterolasRurToolsWindowphpliminny.ohpphplang.ohopho maillonopho men.nhopho medaastreamina.oodpho manhe calonopto queue.phppho salastorce.obdpho samip obdnho sacure-headers obdpte sentry.phpMo sarvicas nhrme session.phpmo slack.phpmo testing-phpmotimezones.phpmoview.phppe webhook-server.php• E contrib› E docs>Ea front-end> M land› E node_modules library root› E phpstan> public> En rescurcesv Oroutespho aninhnpte apL_v2,phpnho console.nhoKeroaioh.© SyneMailbox.php© TextRelayServiceTest.phppto jiminny.phpx 3 Ccpho api.php *555ба declare(strict_types=1);* API routes.* Bsee |Jininny\Providers|RouteServiceProvider* Byac Router Srouter› use ...// ncp.audit MUST stay outernost so its Snext(Srequest) call wraps the auth// and tier guards. Otherwise 401 (auth:api) and 483 (ncp.tier) rejections// short-circuit before McpAuditMiddLeware::handle ever runs and we lose// audit rows for exactly the requests the security log most needs to capture.// McpAuditMiddleware: :writeAuditRow null-checks Srequest-›user(), so writing// pre-auth is safe.Ncp::web( route:) "/mcp', (serverClass: JininnyServer::class)->niddLewareC['ncp.audit'.› Srouter-›group(('middtenare' => ['auth:api']l, static function (Router Srouter): void (...}):> Srouter->orouodlmiddlemare" e>authrao statie functaion(Router Srouter): void (...h):› Srouter-›group(( 'middlemare' => ['apt'Il, static function(Router Srouter): void (...J):7262› Srouter->group(['prefix' »> 'user'], static function (Router Srouter): void (....):- 263› Srouter->group([ 'middleware' => ['auth:api']."profix' →) gas'), statle funetion (Router Srouter): vo1a_ ,55› Srouter-›group(['middleware' => ['auth:aps']), static function (Router Srouter): void (...}):=257Srouter->group(['prefix' => 'page", 'niddlemare' => ['api', 'auth:api')), static function () use (SrouteE 269)› Srouter-group(l'prefix" => "partners", 'aiddlenare' => 'auth:partner-api"), static funetion () use (5roU 271› Srouter-group(['prefix' → 'activity", 'nidatenare' => 'api"), statie funetion () use (Srouter): void ( 273274› Srouter->group(['middleware' => ['auth:api']], static function () use (Srouter) (...}):=273•Srouter-›group(['middlenare' => ['auth:api']l, static function (Router Srouter): void (...}):=['prefix' => "/opportunity/{opportunity}''niddlenare' => ['api']].static function (Router Srouter): void (...).laravellogSF jiminny@localhost] x 4 HSJocal ([iminny@localhost)A console [PROD]A console (EU]A console (STAGING)TcAutoyDo jminnyihacriwitiesaDiusers u. nc-l: On aruser o = u.dUaGlBlYzYoa.status = 'completed"ANo uurd to bind 64f1ac0-1608-4201-8726-0757979da08eeu.uusdAND a.deleted_at IS NULLANDSXTESSELECT 1 FROM tracks tWHERE t.activity_id = a.idAND t.type IN ('audio', "video')EDER BY a.actual_start,time DESCilect * fron teans where id = 19:ilect * fron crn_configurations where provider = 'Ripedcive':CONCAT(u.id, CASE WHEN U.id = t.ouner_id THEN • (onner)' ELSE ** END) AS user_id,UrehazlSa.xt.ouner_id FROM social_accounts sawusers uon urs sansodaolenIIN teans t 1.n<->1: on t.id = u.team_idJERE u,tean 1d = 19 and sa,onoyiden = "oipedoive':*Kun sooaaecounsnmekenoeaalonDATe sochal accounts set onoviden usen token = "Mu:ADCA:--21 K2yuuuaLos2hwo9crunklok4el09cinXoo dAEchohdoVasnyichEynoysovider_refresh_token = ^5034113:195S5731:87c14258f8c813d02767ee975f6844846b6b2bfc',oines = 998919941ERE 1031516provider_user-token": "viu:AQLBAH5-L2/NK2yuuuaLqifzh#b9crUNKtpk4F109minXap_6AE0hDhD0Va1nviCHEvnpvSEAAAAf:1888gkqhk169w8BBwgg"provider refresh_token": "5834113:[TELEGRAM_TOKEN]b2bfc*Montton on old walmoc.ilect * fron crn_fields where type = 'nulti-picklist';ELECT * FROM crn_Layouts WHERE uuid_to_bin('7C327871-fc25-4056-9a0f-44c5a849d65c') = uuid;ELECT * FROM crm layout entities WHERE crn layout id = 282:ELECT * FROM crn_fields WHERE id = 3014; # 1885ELECT * FROM crn_field_vatues WHERE crn_field_id = 3014;00%LXThu 28 May 9:31:50U TextRelayServiceTest~aer henseict+0.can I test it locally first. if I place env from stagingYes. The service relies on a few things you'd need in place:1. Credentials file The constructor expects storage/text-relay.json (a Google service account JSON key file)Gmbtrom sthaind and oince it there2. .env values to copy from stagingGOOGLE TEXTUSERECOOGLE TEXTI HASTGOOGLE_TEXT_RELAY_TOPIC=DEPLOY _REGION=the cnail mailbox address# e.g. txt.jiminny.com or txt.staging.jiminny.com# the Pub/Sub topie name* eu or us3. Run the sync manually via tinker (inside docker_lanp_1):D bashdocker exec -it docker_lamp_1 php artisan tinker• 0app(\Jininny\ServicesVMail\TextRelayServices:class)->sync();Caveat: The service reads from Gmail history and dispatches jobs to the queue. If you don't want it to actuallsend SMS, make sure QUEUE_CONNECTION-syne is not set (cr use a test queue), or just call isForCurrentEnvironmtioh.Ssvc = new class extends \JiminnylServicesVa1l\TextRelayService ( public function _constructlSom Service ssvc-soctServicelcont.aasI then sinsoect a eessade canual1sasg = SgnaitService-susers_gessages-sget(config(*Jiainny-9009le_text_user*), "THE_MESSAGE_ID*)collect (Sasg->getPayload()-»getHeaders())->pluck("value',thut wey von can Mrity what handare tra nehhilm oraesot do ttat macesos alote tha ull evoc muneAsk anything (Xol- @ eodeAdhotvtModereimeelcharies2 4 space:...
|
79494
|
NULL
|
NULL
|
NULL
|
|
79494
|
2787
|
52
|
2026-05-28T06:31:48.521409+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949908521_m2.jpg...
|
PhpStorm
|
faVsco.js – api.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Built-in Preview
Chrome
Firefox
Safari
Sync Changes
Hide This Notification
Code changed:
Hide
2
5
3
16
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
/**
* API routes.
*
* @see \Jiminny\Providers\RouteServiceProvider
*
* @var Router $router
*/
use Illuminate\Routing\Router;
use Illuminate\Support\Collection;
use Jiminny\Component\DealInsights\Forecast\Forecast;
use Jiminny\Component\Router\Routes;
use Jiminny\Contracts\Acl\PermissionEnum;
use Jiminny\Http\Controllers;
use Jiminny\Http\Controllers\API\ActivityController;
use Jiminny\Http\Controllers\API\AiCrmNotesController;
use Jiminny\Http\Controllers\API\ClientTokenController;
use Jiminny\Http\Controllers\API\CrmController;
use Jiminny\Http\Controllers\API\TeamInsights\TeamInsightsAiCallScoringController;
use Jiminny\Http\Controllers\ConferencesOptInOutController;
use Jiminny\Http\Controllers\API\DealRiskController;
use Jiminny\Http\Controllers\API\InstantMeetingController;
use Jiminny\Http\Controllers\API\LanguageController;
use Jiminny\Http\Controllers\API\LiveFeedController;
use Jiminny\Http\Controllers\API\MeetingsController;
use Jiminny\Http\Controllers\API\MessageController;
use Jiminny\Http\Controllers\API\MetadataController;
use Jiminny\Http\Controllers\API\MobileSettingsController;
use Jiminny\Http\Controllers\API\MomentController;
use Jiminny\Http\Controllers\API\NudgeController;
use Jiminny\Http\Controllers\API\NumberAllocatorController;
use Jiminny\Http\Controllers\API\Opportunity\CommentsController;
use Jiminny\Http\Controllers\API\OrganizationLicensesController;
use Jiminny\Http\Controllers\API\OrganizationMembersController;
use Jiminny\Http\Controllers\API\OrganizationRetentionPolicyController;
use Jiminny\Http\Controllers\API\OrganizationRolesController;
use Jiminny\Http\Controllers\API\OrganizationSyncController;
use Jiminny\Http\Controllers\API\Page\OnDemandController;
use Jiminny\Http\Controllers\API\Page\PlaybackController;
use Jiminny\Http\Controllers\API\PartnerController;
use Jiminny\Http\Controllers\API\PhoneNumberController;
use Jiminny\Http\Controllers\API\PlaylistController;
use Jiminny\Http\Controllers\API\Settings\EmailSyncController;
use Jiminny\Http\Controllers\API\SidekickController;
use Jiminny\Http\Controllers\API\SoftphoneController;
use Jiminny\Http\Controllers\API\SubscriptionController;
use Jiminny\Http\Controllers\API\TeamAiAutomationController;
use Jiminny\Http\Controllers\API\TeamAiContextController;
use Jiminny\Http\Controllers\API\TeamController;
use Jiminny\Http\Controllers\API\TeamInsights\ActivityStatsController;
use Jiminny\Http\Controllers\API\TeamInsights\CoachingFeedbacksController;
use Jiminny\Http\Controllers\API\TeamInsights\DashboardController;
use Jiminny\Http\Controllers\API\TeamInsights\EngagementController;
use Jiminny\Http\Controllers\API\TeamInsights\TeamInsightsAutomatedCallScoresController;
use Jiminny\Http\Controllers\API\TeamInsights\ThemeTopicsController;
use Jiminny\Http\Controllers\API\TeamInsights\TopicsInDealsController;
use Jiminny\Http\Controllers\API\TeamInsightsController;
use Jiminny\Http\Controllers\API\Themes\ThemeController;
use Jiminny\Http\Controllers\API\Themes\TopicController;
use Jiminny\Http\Controllers\API\Themes\TopicTriggerController;
use Jiminny\Http\Controllers\API\TranscriptionController;
use Jiminny\Http\Controllers\API\TranslationController;
use Jiminny\Http\Controllers\API\UserAutomatedReports\UserAutomatedReportsController;
use Jiminny\Http\Controllers\API\UserController;
use Jiminny\Http\Controllers\API\VocabularyController;
use Jiminny\Http\Controllers\Auth\ExtensionController;
use Jiminny\Http\Controllers\Auth\SocialController;
use Jiminny\Http\Controllers\ExportController;
use Jiminny\Http\Controllers\Kiosk\ActivityController as KioskActivityController;
use Jiminny\Http\Controllers\Kiosk\AutomatedReportsController;
use Jiminny\Http\Controllers\Kiosk\MediaPipelineController;
use Jiminny\Http\Controllers\Kiosk\OrganizationsController;
use Jiminny\Http\Controllers\Kiosk\PartnersController;
use Jiminny\Http\Controllers\Kiosk\SearchController;
use Jiminny\Http\Controllers\Kiosk\Teams\OnboardController;
use Jiminny\Http\Controllers\NotificationController;
use Jiminny\Http\Controllers\Settings\GroupController;
use Jiminny\Http\Controllers\Settings\JobTitleController;
use Jiminny\Http\Controllers\Settings\PlaybookCategoryController;
use Jiminny\Http\Controllers\Settings\PlaybookController;
use Jiminny\Http\Controllers\Settings\Teams\IntegrationController;
use Jiminny\Http\Controllers\Settings\Teams\InvitationController;
use Jiminny\Http\Controllers\Settings\Teams\TeamActivityController;
use Jiminny\Http\Controllers\Settings\Teams\TeamCoachingSettingsController;
use Jiminny\Http\Controllers\Settings\Teams\TeamConferenceSettingsController;
use Jiminny\Http\Controllers\Settings\Teams\TeamController as OrganizationController;
use Jiminny\Http\Controllers\Settings\Teams\TeamDealInsightsSettingController;
use Jiminny\Http\Controllers\Settings\Teams\TeamMemberController;
use Jiminny\Http\Controllers\Settings\Teams\TeamPhotoController;
use Jiminny\Http\Controllers\Settings\Teams\TeamRecordingSettingsController;
use Jiminny\Http\Controllers\Settings\Teams\TeamSettingsController;
use Jiminny\Http\Controllers\Settings\Teams\TeamSoftphoneSettingsController;
use Jiminny\Http\Controllers\TeamSetupController;
use Jiminny\Models;
use Jiminny\Models\PlaybackTheme;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\User;
use Jiminny\Models\Vocabulary;
use Jiminny\Repositories;
use Jiminny\Mcp\Servers\JiminnyServer;
use Laravel\Mcp\Facades\Mcp;
// mcp.audit MUST stay outermost so its $next($request) call wraps the auth
// and tier guards. Otherwise 401 (auth:api) and 403 (mcp.tier) rejections
// short-circuit before McpAuditMiddleware::handle ever runs and we lose
// audit rows for exactly the requests the security log most needs to capture.
// McpAuditMiddleware::writeAuditRow null-checks $request->user(), so writing
// pre-auth is safe.
Mcp::web('/mcp', JiminnyServer::class)
->middleware(['mcp.audit', 'auth:api', 'mcp.tier']);
$router->group(['middleware' => ['auth:api']], static function (Router $router): void {
$router->get('/metadata/extension-app', [MetadataController::class, 'extension']);
$router->get('/', [NumberAllocatorController::class, 'generate']);
$router->delete('/key-moment/{activityMoment}', [MomentController::class, 'destroy']);
$router->post('/instant-meeting/start', [InstantMeetingController::class, 'postRequestBotAtUrl'])
->middleware(['permission:' . PermissionEnum::RECORD_MEETING->value])
->name('instant-meeting.start');
// Meeting creation endpoint for Outlook add-in
$router->post('/meetings', [MeetingsController::class, 'create'])
->middleware(['permission:' . PermissionEnum::RECORD_MEETING->value])
->name('meetings.create');
// Number provisioning and search.
$router->get('/phone-numbers', [NumberAllocatorController::class, 'generate']);
$router->get('/phone-numbers/{number}', [PhoneNumberController::class, 'number']);
$router->group(['prefix' => 'deal-insights'], static function (Router $router): void {
$router->get('/forecast', [
Controllers\API\DealInsights\DealsController::class,
'getForecast',
])->defaults('period', Forecast::PERIOD_QUARTER);
$router->get('/deals/{stage?}', [
Controllers\API\DealInsights\DealsController::class,
'list',
])->defaults('stage', \Jiminny\Component\DealInsights\CriteriaInterface::STAGE_ALL);
$router->get('/details/details-daily/{opportunityId}/{date}', [
Controllers\API\DealInsights\DealsController::class,
'detailsDaily',
]);
$router->put('/deals/{opportunity}/edit-fields', [
Controllers\API\DealInsights\DealsController::class,
'updateFields',
]);
$router->get('/externalId/{dealId}', [
Controllers\API\DealInsights\DealsController::class,
'externalDealId',
]);
$router->put('/dealRisk/{dealRisk}', [DealRiskController::class, 'toggleActivity']);
});
$router->get('/team-insights/users', [TeamInsightsController::class, 'fetchUsers'])
->name('team_insights.users');
$router->get('/team-insights/dashboard', [DashboardController::class, 'fetch'])
->name('team_insights.dashboard');
// Team Insights - Coaching Feedbacks
$router->get('/team-insights/coaching-feedbacks-over-time', [CoachingFeedbacksController::class, 'fetch'])
->name('team_insights.coaching_feedbacks_over_time');
$router
->get('/team-insights/coaching-feedbacks-over-time/download', [CoachingFeedbacksController::class, 'download'])
->name('team_insights.coaching_feedbacks_over_time.download');
$router->get(
'/team-insights/coaching-feedbacks-over-time/drill-down',
[CoachingFeedbacksController::class, 'drillDown'],
)->name('team_insights.coaching_feedbacks_over_time.drill_down');
// Team Insights - Automated Call Scores
$router->get(
'/team-insights/automated-call-scores-over-time',
[TeamInsightsAutomatedCallScoresController::class, 'index'],
)->name('team_insights.automated_call_scores_over_time.index');
$router->get(
'/team-insights/automated-call-scores-over-time/drill-down',
[TeamInsightsAutomatedCallScoresController::class, 'show'],
)->name('team_insights.automated_call_scores_over_time.show');
// Team Insights - AI Call Scoring
$router->get(
'/team-insights/ai-call-scoring-over-time',
[TeamInsightsAiCallScoringController::class, 'index'],
)->name('team_insights.ai_call_scoring_over_time.index');
$router->get(
'/team-insights/ai-call-scoring-over-time/drill-down',
[TeamInsightsAiCallScoringController::class, 'show'],
)->name('team_insights.ai_call_scoring_over_time.show');
$router->get('/team-insights/engagement', [ActivityStatsController::class, 'fetch'])
->name('team_insights.engagement');
$router->get('/team-insights/engagement/drill-down/{engagementType}', [ActivityStatsController::class, 'drillDown'])
->name('team_insights.engagement.drill_down');
$router->get('/team-insights/topics', [ThemeTopicsController::class, 'getTopics'])
->name('team_insights.topics.index');
$router->get('/team-insights/topics/{topic}', [ThemeTopicsController::class, 'fetch'])
->name('team_insights.topics.show');
$router->get('/team-insights/topics/{topic}/drill-down', [ThemeTopicsController::class, 'drillDown'])
->name('team_insights.topics.drill_down');
$router->group(['prefix' => 'team-insights'], static function (Router $router): void {
$router->group(['prefix' => 'conversations'], static function (Router $router): void {
$router->get('/', [
Controllers\API\TeamInsights\ConversationsController::class,
'fetch',
]);
$router->group(['prefix' => 'drill-down'], static function (Router $router): void {
$router
->get('/{activityChannel}/{drillDownType}', [
Controllers\API\TeamInsights\ConversationsController::class,
'drillDown',
])
->where(
'activityChannel',
Collection::make(Models\Activity::CHANNELS)->join('|'),
)
->where(
'drillDownType',
Collection::make(Repositories\TeamInsightsRepository::CONVERSATION_DRILLDOWNS)
->join('|'),
);
});
});
$router->group(['prefix' => 'coaching'], static function (Router $router): void {
$router->get('/', [EngagementController::class, 'fetch']);
$router->group(['prefix' => 'drill-down'], static function (Router $router): void {
$router
->get('/{coachingType}/{drillDownType?}', [EngagementController::class, 'drillDown'])
->where(
'coachingType',
Collection::make(EngagementController::COACHING_TYPES)->join('|'),
)
->where(
'drillDownType',
Collection::make(EngagementController::COACHING_DRILLDOWNS)->join('|'),
);
});
});
});
$router->get('/topics-in-deals', [TopicsInDealsController::class, 'topics'])
->name('topics_in_deals.topics');
$router->get('/topics-in-deals/topic-triggers', [TopicsInDealsController::class, 'topicTriggers'])
->name('topics_in_deals.topic_triggers');
$router->get('/compare-topics-in-deals', [TopicsInDealsController::class, 'comparison'])
->name('topics_in_deals.comparison');
// CRM actions.
$router->group(['prefix' => 'crm'], static function (Router $router): void {
$router->get('/search', [CrmController::class, 'search']);
$router->get('/opportunity', [CrmController::class, 'opportunities']);
$router->get('/customers', [CrmController::class, 'customers']);
$router->get('/accounts', [CrmController::class, 'accounts']);
$router->get('/contacts', [CrmController::class, 'contacts']);
$router->get('/leads', [CrmController::class, 'leads']);
$router->get('/tasks', [CrmController::class, 'activities']);
$router->get('/layouts', [CrmController::class, 'layouts']);
});
// AI CRM notes.
$router->group(['prefix' => 'ai-crm-notes'], static function (Router $router): void {
$router->get('/activity/{activity}', [AiCrmNotesController::class, 'getByActivity']);
$router->post('/activity/{activity}/log-to-crm', [AiCrmNotesController::class, 'logToCrmByActivity']);
$router->post('/activity/{activity}/discard', [AiCrmNotesController::class, 'discardByActivity']);
$router->get('/deal/{opportunity}', [AiCrmNotesController::class, 'getByOpportunity']);
$router->post('/deal/{opportunity}/log-to-crm', [AiCrmNotesController::class, 'logToCrmByOpportunity']);
$router->post('/deal/{opportunity}/discard', [AiCrmNotesController::class, 'discardByOpportunity']);
});
// Automated Reports
$router->post('/automated-reports/interest', [UserAutomatedReportsController::class, 'trackInterest']);
$router->group(
[
'prefix' => 'automated-reports',
'middleware' => 'can:canAccessAiReports,' . User::class,
],
static function (Router $router): void {
$router->get('/', [UserAutomatedReportsController::class, 'list']);
$router->delete('/{uuid}', [UserAutomatedReportsController::class, 'delete']);
}
);
// Setup New Team / Trial
$router->get('/features', [TeamSetupController::class, 'features']);
$router->get('/tiers', [TeamSetupController::class, 'tiers']);
$router->get('/calendars', [TeamSetupController::class, 'calendars']);
$router->get('/crm-services', [TeamSetupController::class, 'crmServices']);
$router->get('/connect-providers', [TeamSetupController::class, 'connectProviders']);
$router->get('/integration-app-token', [TeamSetupController::class, 'integrationAppToken']);
$router->post('/integration-app-connect', [TeamSetupController::class, 'integrationAppConnect']);
// Notifications
$router->get('/notifications/recent', [NotificationController::class, 'notifications']);
$router->put('/notifications/read', [NotificationController::class, 'markAsRead']);
$router->put('/notifications/read-multiple', [NotificationController::class, 'markMultipleAsRead']);
$router->put('/notifications/read-all', [NotificationController::class, 'markAllAsRead']);
// Live feed
$router->get('/live-feed', [LiveFeedController::class, 'liveFeedItems']);
// Languages
$router->get('/languages', [LanguageController::class, 'list']);
// The whole settings section will be moved out in a separate file
$router->group(['prefix' => '/settings'], static function (Router $router): void {
$router->group(['prefix' => '/organizations'], static function (Router $router): void {
$router
->middleware(['can:kiosk,' . User::class])
->post('/', [OrganizationController::class, 'store'])
->name('kiosk.organizations.store');
$router->group(['prefix' => '{team}', 'middleware' => ['teamMember']], static function (Router $router) {
// Sync fields and team metadata
$router->post('/fields/sync', [OrganizationSyncController::class, 'index'])
->name('api.sync.fields');
// Conference Preferences.
$router->post('/bot-avatar', [TeamPhotoController::class, 'updateBotAvatar'])
->name('update.bot.avatar');
// Roles.
$router->get('/roles', [OrganizationRolesController::class, 'index'])
->name('api.roles.index');
$router->group(
['middleware' => 'permission:' . PermissionEnum::MANAGE_RETENTION_POLICY->value],
static function (Router $router): void {
$router->get('/retention-policy', [OrganizationRetentionPolicyController::class, 'index'])
->name('api.retention_policy.index');
$router->post('/retention-policy', [OrganizationRetentionPolicyController::class, 'store'])
->name('api.retention_policy.update');
}
);
$router->group(
['middleware' => 'permission:' . PermissionEnum::MANAGE_USERS->value],
static function (Router $router): void {
// Invitations.
$router->get('/invitations', [InvitationController::class, 'index'])
->name('api.invitations.index');
$router->post('/invitations/{invitation}', [InvitationController::class, 'resend'])
->name('api.invitations.resend');
$router->delete('/invitations/{invitation}', [InvitationController::class, 'destroy'])
->name('api.invitations.delete');
$router->post('/invitations', [InvitationController::class, 'store'])
->name('api.invitations.store');
},
);
$router->group(
['middleware' => 'permission:' . PermissionEnum::MANAGE_TEAM->value],
static function (Router $router): void {
// Groups.
$router->post('/groups', [GroupController::class, 'store']);
$router->get('/groups/{group}', [GroupController::class, 'show']);
$router->put('/groups/{group}', [GroupController::class, 'update']);
$router->put('/group/{group}/scope', [GroupController::class, 'updateGroupScope']);
$router->post('/group/{group}/dealRisks', [DealRiskController::class, 'updateSettings']);
// Sidekick settings
$router->group(
['middleware' => 'permission:' . PermissionEnum::MANAGE_SIDEKICK->value],
static function (Router $router): void {
$router->get('/sidekick', [SidekickController::class, 'getSidekickSettings']);
$router
->post(
'/group/{group}/sidekick',
[SidekickController::class, 'setSidekickSettings'],
)
->middleware(['can:updateSidekickSettings,group'])
->name('api.sidekick_settings.update');
$router
->post('/sidekick', [SidekickController::class, 'setSidekickSettings'])
->middleware(['permission:' . PermissionEnum::UPDATE_ALL_SIDEKICK_SETTINGS->value])
->name('api.sidekick_settings.update_all');
},
);
$router->get('/deal-insights', [TeamDealInsightsSettingController::class, 'index']);
$router->patch('/deal-insights', [TeamDealInsightsSettingController::class, 'update']);
// CRM Layout Management
$router->group(['prefix' => 'layouts'], static function (Router $router): void {
$router->get(
'/{type}',
[Controllers\API\LayoutManagementController::class, 'list'],
)->name('layouts.list');
$router->put(
'/{layout}',
[Controllers\API\LayoutManagementController::class, 'update'],
)->name('layouts.update');
});
// Users.
$router->put('/users/{user}', [TeamMemberController::class, 'update'])
->middleware(['permission:' . PermissionEnum::MANAGE_USERS->value])
->name('api.users.update');
$router->delete('/users/{user}', [TeamMemberController::class, 'deactivate'])
->middleware(['permission:' . PermissionEnum::MANAGE_USERS->value])
->name('api.users.deactivate');
$router->group(
[
'prefix' => 'vocabulary',
'middleware' => 'can:manage,' . Vocabulary::class,
],
static function (Router $router): void {
$router
->get('/', [VocabularyController::class, 'list'])
->name('api.vocabulary.index');
$router
->post('/', [VocabularyController::class, 'update'])
->name('api.vocabulary.create');
$router->group(['prefix' => '{vocabulary}'], static function (Router $router): void {
$router
->put('/', [VocabularyController::class, 'update'])
->middleware('can:update,vocabulary')
->name('api.vocabulary.update');
$router
->delete('/', [VocabularyController::class, 'delete'])
->middleware('can:delete,vocabulary')
->name('api.vocabulary.delete');
});
},
);
$router->group(['prefix' => 'ai-context'], static function (Router $router): void {
$router->get('/', [TeamAiContextController::class, 'index'])
->name('api.ai_context.get');
$router->post('/', [TeamAiContextController::class, 'store'])
->name('api.ai_context.store');
});
$router->group(['prefix' => 'ai-automation'], static function (Router $router): void {
$router->post('/fields/test-prompt', [TeamAiAutomationController::class, 'testCrmAiPrompt'])
->name('api.automation.templates.fields.test-prompt');
// List CRM fields per object type
$router->get('/fields/{objectType}', [TeamAiAutomationController::class, 'fields'])
->name('api.automation.fields');
// List DealStages fields per object type
$router->get('/stages', [TeamAiAutomationController::class, 'stages'])
->name('api.automation.stages');
// Create CRM AI template
$router->post('/templates', [TeamAiAutomationController::class, 'createTemplate'])
->name('api.automation.templates.create');
// Export CRM updates
$router->post('/templates/export-crm-updates', [TeamAiAutomationController::class, 'exportTemplateCrmUpdates'])
->name('api.automation.templates.export-crm-updates');
// Update CRM AI template
$router->put('/templates/{crmTemplate}', [TeamAiAutomationController::class, 'updateTemplate'])
->name('api.automation.templates.update');
// Delete CRM AI template
$router->delete('/templates/{crmTemplate}', [TeamAiAutomationController::class, 'deleteTemplate'])
->name('api.automation.templates.delete');
// List all CRM AI templates
$router->get('/templates', [TeamAiAutomationController::class, 'templates'])
->name('api.automation.templates.list');
// Create CRM AI template field
$router->post('/templates/{crmTemplate}/fields', [TeamAiAutomationController::class, 'createField'])
->name('api.automation.templates.fields.create');
// Update CRM AI template field
$router->put('/templates/{crmTemplate}/fields/{crmTemplateField}', [TeamAiAutomationController::class, 'updateField'])
->name('api.automation.templates.fields.update');
// Delete CRM AI template field
$router->delete('/templates/{crmTemplate}/fields/{crmTemplateField}', [TeamAiAutomationController::class, 'deleteField'])
->name('api.automation.templates.fields.delete');
});
$router->group(['prefix' => 'ai-call-scoring'], static function (Router $router): void {
// Create AI scorecard
$router->post('/ai-scorecards', [Controllers\API\AiCallScoring\AiScorecardController::class, 'createAiScorecard'])
->name('api.ai-call-scoring.ai-scorecards.create');
// Update AI scorecard
$router->put('/ai-scorecards/{aiScorecard}', [Controllers\API\AiCallScoring\AiScorecardController::class, 'updateAiScorecard'])
->name('api.ai-call-scoring.ai-scorecards.update');
// Delete AI scorecard
$router->delete('/ai-scorecards/{aiScorecard}', [Controllers\API\AiCallScoring\AiScorecardController::class, 'deleteAiScorecard'])
->name('api.ai-call-scoring.ai-scorecards.delete');
// Test AI scorecard prompt
$router->post(
'/ai-scorecards/{aiScorecard}/test-prompt',
[
Controllers\API\AiCallScoring\AiScorecardController::class,
'testAiScorecardPrompt',
]
)
->name('api.ai-call-scoring.ai-scorecards.test-prompt');
// Create AI Scorecard rule
$router->post('/ai-scorecards/{aiScorecard}/ai-scorecard-rules', [Controllers\API\AiCallScoring\AiScorecardRuleController::class, 'createRule'])
->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.create');
// Update AI Scorecard rule
$router->put('/ai-scorecards/{aiScorecard}/ai-scorecard-rules/{aiScorecardRule}', [Controllers\API\AiCallScoring\AiScorecardRuleController::class, 'updateAiScorecardRule'])
->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.update');
// Delete AI Scorecard rule
$router->delete('/ai-scorecards/{aiScorecard}/ai-scorecard-rules/{aiScorecardRule}', [Controllers\API\AiCallScoring\AiScorecardRuleController::class, 'deleteAiScorecardRule'])
->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.delete');
});
// Theme, topics, triggers
$router->get('/themes', [ThemeController::class, 'list']);
$router
->post('/themes', [ThemeController::class, 'updateTheme'])
->middleware('can:manage,' . PlaybackTheme::class)
->name('api.theme.create');
$router->group(
[
'prefix' => 'theme/{theme}',
'middleware' => 'can:update,theme',
],
static function (Router $router): void {
$router
->put('/', [ThemeController::class, 'updateTheme'])
->name('api.theme.update');
$router
->delete('/', [ThemeController::class, 'deleteTheme'])
->middleware('can:delete,theme')
->name('api.theme.delete');
$router
->post('/topics', [TopicController::class, 'updateTopic'])
->middleware('can:createTopic,theme')
->name('api.topic.create');
$router->group(
[
'prefix' => 'topic/{topic}',
'middleware' => 'can:update,topic',
],
static function (Router $router): void {
$router
->put('/', [TopicController::class, 'updateTopic'])
->name('api.topic.update');
$router
->delete('/', [TopicController::class, 'deleteTopic'])
->middleware('can:delete,topic')
->name('api.topic.delete');
$router
->post('/triggers', [TopicTriggerController::class, 'updateTrigger'])
->middleware('can:createTrigger,topic')
->name('api.topic_trigger.create');
$router->group(
[
'prefix' => 'trigger/{topicTrigger}',
'middleware' => 'can:update,topicTrigger',
],
static function (Router $router): void {
$router
->put('/', [TopicTriggerController::class, 'updateTrigger'])
->name('api.topic_trigger.update');
$router
->delete('/', [TopicTriggerController::class, 'deleteTrigger'])
->middleware('can:delete,topicTrigger')
->name('api.topic_trigger.delete');
},
);
},
);
},
);
$router->post('/themes/import', [Controllers\API\Themes\ImportTopicTriggerController::class, 'importThemes']);
$router->get('/themes/export', [Controllers\API\Themes\ExportTopicTriggerController::class, 'exportThemes']);
// Auto-scoring
$router->group(['prefix' => '/scorecards'], static function (Router $router) {
$router->get('/', [Controllers\API\Scorecards\ScorecardController::class, 'list']);
$router->post('/', [Controllers\API\Scorecards\ScorecardController::class, 'create']);
$router->delete('/{scorecard}', [
Controllers\API\Scorecards\ScorecardController::class,
'delete',
]);
$router->post('/validate-name', [
Controllers\API\Scorecards\ScorecardController::class,
'validateNameExists',
]);
$router->get('/enabled-scorecard', [
Controllers\API\Scorecards\ScorecardController::class,
'getEnabledScorecard',
]);
$router->get('/affected-scorecards', [
Controllers\API\Scorecards\ScorecardController::class,
'getAffectedScorecards',
]);
$router->group(['prefix' => '/{scorecard}'], static function (Router $router) {
$router->put('/', [
Controllers\API\Scorecards\ScorecardController::class,
'update',
]);
$router->delete('/', [
Controllers\API\Scorecards\ScorecardController::class,
'delete',
]);
$router->post('/rules', [
Controllers\API\Scorecards\ScorecardRuleController::class,
'create',
]);
$router->post('/rules/{scorecardRule}', [
Controllers\API\Scorecards\ScorecardRuleController::class,
'update',
]);
$router->delete('/rules/{scorecardRule}', [
Controllers\API\Scorecards\ScorecardRuleController::class,
'delete',
]);
$router->post('/rules/{scorecardRule}/update-order', [
Controllers\API\Scorecards\ScorecardRuleController::class,
'updateOrder',
]);
});
});
// Coaching Playbook.
Route::get('/playbooks', [PlaybookController::class, 'all']);
Route::get('/playbooksTree', [PlaybookController::class, 'tree']);
Route::put('/playbooks/{playbook}', [PlaybookController::class, 'update']);
Route::post('/playbooks', [PlaybookController::class, 'store']);
Route::delete('/playbooks/{playbook}', [PlaybookController::class, 'destroy']);
Route::prefix('/playbooks/{playbook}')->group(static function () {
// Playbook Categories.
Route::get('/categories', [PlaybookCategoryController::class, 'all']);
Route::put('/categories/sequence', [PlaybookCategoryController::class, 'sequence']); // Respect order.
Route::put('/categories/{category}', [PlaybookCategoryController::class, 'update']);
Route::post('/categories', [PlaybookCategoryController::class, 'store']);
Route::post('/test-prompt', [PlaybookController::class, 'testAiActivityTypePrompt']);
Route::post('/prompt-suggestion', [PlaybookController::class, 'getPromptSuggestion']);
Route::delete('/categories/{category}', [PlaybookCategoryController::class, 'destroy']);
Route::prefix('/categories/{category}')->group(static function () {
// Coaching Sections
Route::get('/coaching-section', [Controllers\Settings\Coaching\SectionsController::class, 'all']);
Route::put('/coaching-section/sequence', [Controllers\Settings\Coaching\SectionsController::class, 'sequence']);
Route::put('/coaching-section/{coachingSection}', [Controllers\Settings\Coaching\SectionsController::class, 'update']);
Route::post('/coaching-section', [Controllers\Settings\Coaching\SectionsController::class, 'store']);
Route::delete('/coaching-section/{coachingSection}', [Controllers\Settings\Coaching\SectionsController::class, 'destroy']);
Route::prefix('coaching-section/{coachingSection}')->group(static function () {
// Coaching Section Criteria
Route::get('/coaching-section-criterion', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'all']);
Route::put('/coaching-section-criterion/sequence', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'sequence']);
Route::put('/coaching-section-criterion/{coachingSectionCriterion}', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'update']);
Route::post('/coaching-section-criterion', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'store']);
Route::delete('/coaching-section-criterion/{coachingSectionCriterion}', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'destroy']);
});
});
});
},
);
// List all AI scorecards (accessible to all team members, no MANAGE_TEAM required)
$router->get('/ai-call-scoring/ai-scorecards', [Controllers\API\AiCallScoring\AiScorecardController::class, 'aiScorecards'])
->name('api.ai-call-scoring.ai-scorecards.list');
$router->middleware(['permission:' . PermissionEnum::MANAGE_ORGANIZATION_SETTINGS->value])
->group(static function (Router $router): void {
// Job Titles.
$router->get('/job-titles', [JobTitleController::class, 'all']);
$router->put('/job-titles/{job}', [JobTitleController::class, 'update']);
$router->post('/job-titles', [JobTitleController::class, 'store']);
$router->delete('/job-titles/{job}', [JobTitleController::class, 'destroy']);
// Team Settings.
$router->put('/', [TeamSettingsController::class, 'update']);
$router->put('/notifications', [TeamSettingsController::class, 'updateNotifications']);
$router->put('/team-conference', [TeamConferenceSettingsController::class, 'update']);
$router->put('/team-coaching', [TeamCoachingSettingsController::class, 'update']);
$router->put('/team-softphone', [TeamSoftphoneSettingsController::class, 'update']);
$router->put('/owner', [Controllers\Settings\Teams\OrganizationSettingsController::class, 'updateOwner']);
$router->put('/team-recording', [TeamRecordingSettingsController::class, 'update'])
->middleware(['permission:' . PermissionEnum::MANAGE_RECORDING->value]);
// Key Moments.
$router->get('/moments/{moment}', [Controllers\Settings\MomentController::class, 'show']);
$router->put('/moments/{moment}', [Controllers\Settings\MomentController::class, 'update']);
$router->post('/moments', [Controllers\Settings\MomentController::class, 'store']);
$router->put('/activity', [TeamActivityController::class, 'store']);
// Team Domains.
$router->get('/domains', [Controllers\Settings\Teams\TeamDomainsController::class, 'all']);
$router->post('/domains', [Controllers\Settings\Teams\TeamDomainsController::class, 'create']);
$router->delete('/domains/{teamDomain}', [Controllers\Settings\Teams\TeamDomainsController::class, 'destroy']);
});
});
});
});
// Integrations
$router->group(['middleware' => 'permission:' . PermissionEnum::MANAGE_INTEGRATIONS->value], static function (Router $router): void {
$router->post('/integrations', [IntegrationController::class, 'internal'])
->name('api.integrations.internal');
$router->put('/integrations', [IntegrationController::class, 'toggleStatus'])
->name('api.integrations.toggle_status');
$router->delete('/integrations/{provider}', [IntegrationController::class, 'delete'])
->name('api.integrations.delete');
});
$router->get('/integrations', [IntegrationController::class, 'all'])
->middleware('permission:' . PermissionEnum::READ_INTEGRATIONS->value)
->name('api.integrations.index');
// Slack API for getting slack channels list
$router->get('{notificationProvider}/channels', [Controllers\NotificationProviderController::class, 'channels']);
// Team actions. XXX: These all need moving out to their own controllers.
$router->group(['prefix' => 'organizations'], static function (Router $router): void {
$router->get('current', [TeamController::class, 'current']);
$router->group(['prefix' => '{team}', 'middleware' => ['teamMember']], static function (Router $router): void {
$router->get('/', [TeamController::class, 'show']);
$router->get('/categories', [TeamController::class, 'categories']);
$router->get('/stages', [TeamController::class, 'stages']);
$router->get('/users', [OrganizationMembersController::class, 'index'])
->name('organization.members.index');
$router
->get('/users/download', [OrganizationMembersController::class, 'download'])
->middleware('permission:' . PermissionEnum::MANAGE_USERS->value)
->name('organization.members.download');
$router->get('/licensed-roles', [OrganizationLicensesController::class, 'index'])
->middleware('permission:' . PermissionEnum::MANAGE_BILLING->value)
->name('organization.licensed-roles.index');
$router->get('/invitations', [TeamController::class, 'invitations']);
$router->get('/groups', [TeamController::class, 'groups']);
$router->delete('/groups/{group}', [TeamController::class, 'deleteGroup'])
->middleware(['permission:' . PermissionEnum::DELETE_TEAM->value])
->name('api.groups.delete');
$router->get('/job-titles', [TeamController::class, 'jobTitles']);
$router->get('/slugs', [TeamController::class, 'slugs']);
$router->put('/api-token', [TeamController::class, 'generateApiToken'])
->middleware(['permission:' . PermissionEnum::MANAGE_ORGANIZATION_SETTINGS->value]);
$router->get('/key-moments', [MomentController::class, 'all']);
});
});
// Internal Kiosk. This whole section will be moved out to a separate file
$router
->prefix('kiosk')
->middleware('can:kiosk,' . User::class)
->group(static function (Router $router): void {
// Partner actions.
$router->get('/partners', [PartnersController::class, 'index']);
// User actions.
$router->post('/users/search', [SearchController::class, 'performBasicSearch']);
// Team actions.
$router->prefix('organizations')->group(static function (Router $router): void {
$router->get('/', [OrganizationsController::class, 'show']);
$router->put('/{team}', [OrganizationController::class, 'edit'])
->name('kiosk.organizations.edit');
$router->get('/{team}/users', [OrganizationMembersController::class, 'index'])
->name('kiosk.organization.members.index');
$router->get('onboardable', [OnboardController::class, 'available']);
$router->delete('/{team}', [OrganizationsController::class, 'deactivateAccounts']);
});
// Automated reports
// api/v1/kiosk/automated-reports
$router->prefix('automated-reports')->group(static function (Router $router): void {
$router->get('/form-data', [AutomatedReportsController::class, 'getCreateForm']);
$router->get('/form-data/{reportUuid}', [AutomatedReportsController::class, 'getEditForm']);
$router->post('/filters', [AutomatedReportsController::class, 'getFilters']);
$router->post('/', [AutomatedReportsController::class, 'create']);
$router->put('/{reportUuid}', [AutomatedReportsController::class, 'update']);
$router->patch('/{reportUuid}', [AutomatedReportsController::class, 'partialUpdate']);
$router->get('/', [AutomatedReportsController::class, 'list']);
$router->get('/{reportUuid}', [AutomatedReportsController::class, 'get']);
$router->delete('/{reportUuid}', [AutomatedReportsController::class, 'delete']);
$router->post('/activities-count', [AutomatedReportsController::class, 'getActivitiesCount']);
$router->get('/{reportUuid}/reports-count', [AutomatedReportsController::class, 'getReportsCount']);
});
// Activity actions.
$router->post('/activity/search', [SearchController::class, 'performActivitySearch']);
$router->prefix('activity/{activity}')->group(static function (Router $router): void {
$router->post('check-playable', [SearchController::class, 'performActivityCheckPlayable']);
$router->post('reset-crm-log', [SearchController::class, 'performResetCrmLogActivity']);
$router->get('diarize-via-transcript', [KioskActivityController::class, 'diarizeViaTranscript']);
$router->post('diarize-via-transcript', [KioskActivityController::class, 'diarizeViaTranscript']);
$router->get('media-pipeline', [MediaPipelineController::class, 'getPipes']);
$router->post('media-pipeline', [MediaPipelineController::class, 'updatePipe']);
$router->post('language', [KioskActivityController::class, 'updateLanguage']);
$router->post('trim', [KioskActivityController::class, 'trimActivity']);
$router->get('troubleshoot', [KioskActivityController::class, 'troubleshootActivity']);
$router->get('transcription', [KioskActivityController::class, 'getTranscriptions']);
$router->post('speakers', [KioskActivityController::class, 'addSpeakers']);
$router->post('crm-f...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09740692,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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.8374335,"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":"TextRelayServiceTest","depth":6,"bounds":{"left":0.85272604,"top":0.019952115,"width":0.062832445,"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 'TextRelayServiceTest'","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 'TextRelayServiceTest'","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":"Built-in Preview","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":"Chrome","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":"Firefox","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":"Safari","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":"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.35571808,"top":0.10055866,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"5","depth":4,"bounds":{"left":0.36569148,"top":0.10055866,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"3","depth":4,"bounds":{"left":0.3756649,"top":0.10055866,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"16","depth":4,"bounds":{"left":0.3856383,"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.39694148,"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.40425533,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\n/**\n * API routes.\n *\n * @see \\Jiminny\\Providers\\RouteServiceProvider\n *\n * @var Router $router\n */\n\nuse Illuminate\\Routing\\Router;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\DealInsights\\Forecast\\Forecast;\nuse Jiminny\\Component\\Router\\Routes;\nuse Jiminny\\Contracts\\Acl\\PermissionEnum;\nuse Jiminny\\Http\\Controllers;\nuse Jiminny\\Http\\Controllers\\API\\ActivityController;\nuse Jiminny\\Http\\Controllers\\API\\AiCrmNotesController;\nuse Jiminny\\Http\\Controllers\\API\\ClientTokenController;\nuse Jiminny\\Http\\Controllers\\API\\CrmController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\TeamInsightsAiCallScoringController;\nuse Jiminny\\Http\\Controllers\\ConferencesOptInOutController;\nuse Jiminny\\Http\\Controllers\\API\\DealRiskController;\nuse Jiminny\\Http\\Controllers\\API\\InstantMeetingController;\nuse Jiminny\\Http\\Controllers\\API\\LanguageController;\nuse Jiminny\\Http\\Controllers\\API\\LiveFeedController;\nuse Jiminny\\Http\\Controllers\\API\\MeetingsController;\nuse Jiminny\\Http\\Controllers\\API\\MessageController;\nuse Jiminny\\Http\\Controllers\\API\\MetadataController;\nuse Jiminny\\Http\\Controllers\\API\\MobileSettingsController;\nuse Jiminny\\Http\\Controllers\\API\\MomentController;\nuse Jiminny\\Http\\Controllers\\API\\NudgeController;\nuse Jiminny\\Http\\Controllers\\API\\NumberAllocatorController;\nuse Jiminny\\Http\\Controllers\\API\\Opportunity\\CommentsController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationLicensesController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationMembersController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationRetentionPolicyController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationRolesController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationSyncController;\nuse Jiminny\\Http\\Controllers\\API\\Page\\OnDemandController;\nuse Jiminny\\Http\\Controllers\\API\\Page\\PlaybackController;\nuse Jiminny\\Http\\Controllers\\API\\PartnerController;\nuse Jiminny\\Http\\Controllers\\API\\PhoneNumberController;\nuse Jiminny\\Http\\Controllers\\API\\PlaylistController;\nuse Jiminny\\Http\\Controllers\\API\\Settings\\EmailSyncController;\nuse Jiminny\\Http\\Controllers\\API\\SidekickController;\nuse Jiminny\\Http\\Controllers\\API\\SoftphoneController;\nuse Jiminny\\Http\\Controllers\\API\\SubscriptionController;\nuse Jiminny\\Http\\Controllers\\API\\TeamAiAutomationController;\nuse Jiminny\\Http\\Controllers\\API\\TeamAiContextController;\nuse Jiminny\\Http\\Controllers\\API\\TeamController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\ActivityStatsController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\CoachingFeedbacksController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\DashboardController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\EngagementController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\TeamInsightsAutomatedCallScoresController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\ThemeTopicsController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\TopicsInDealsController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsightsController;\nuse Jiminny\\Http\\Controllers\\API\\Themes\\ThemeController;\nuse Jiminny\\Http\\Controllers\\API\\Themes\\TopicController;\nuse Jiminny\\Http\\Controllers\\API\\Themes\\TopicTriggerController;\nuse Jiminny\\Http\\Controllers\\API\\TranscriptionController;\nuse Jiminny\\Http\\Controllers\\API\\TranslationController;\nuse Jiminny\\Http\\Controllers\\API\\UserAutomatedReports\\UserAutomatedReportsController;\nuse Jiminny\\Http\\Controllers\\API\\UserController;\nuse Jiminny\\Http\\Controllers\\API\\VocabularyController;\nuse Jiminny\\Http\\Controllers\\Auth\\ExtensionController;\nuse Jiminny\\Http\\Controllers\\Auth\\SocialController;\nuse Jiminny\\Http\\Controllers\\ExportController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\ActivityController as KioskActivityController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\AutomatedReportsController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\MediaPipelineController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\OrganizationsController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\PartnersController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\SearchController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\Teams\\OnboardController;\nuse Jiminny\\Http\\Controllers\\NotificationController;\nuse Jiminny\\Http\\Controllers\\Settings\\GroupController;\nuse Jiminny\\Http\\Controllers\\Settings\\JobTitleController;\nuse Jiminny\\Http\\Controllers\\Settings\\PlaybookCategoryController;\nuse Jiminny\\Http\\Controllers\\Settings\\PlaybookController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\IntegrationController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\InvitationController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamActivityController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamCoachingSettingsController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamConferenceSettingsController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamController as OrganizationController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamDealInsightsSettingController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamMemberController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamPhotoController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamRecordingSettingsController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamSettingsController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamSoftphoneSettingsController;\nuse Jiminny\\Http\\Controllers\\TeamSetupController;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\PlaybackTheme;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models\\Vocabulary;\nuse Jiminny\\Repositories;\nuse Jiminny\\Mcp\\Servers\\JiminnyServer;\nuse Laravel\\Mcp\\Facades\\Mcp;\n\n// mcp.audit MUST stay outermost so its $next($request) call wraps the auth\n// and tier guards. Otherwise 401 (auth:api) and 403 (mcp.tier) rejections\n// short-circuit before McpAuditMiddleware::handle ever runs and we lose\n// audit rows for exactly the requests the security log most needs to capture.\n// McpAuditMiddleware::writeAuditRow null-checks $request->user(), so writing\n// pre-auth is safe.\nMcp::web('/mcp', JiminnyServer::class)\n ->middleware(['mcp.audit', 'auth:api', 'mcp.tier']);\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/metadata/extension-app', [MetadataController::class, 'extension']);\n\n $router->get('/', [NumberAllocatorController::class, 'generate']);\n $router->delete('/key-moment/{activityMoment}', [MomentController::class, 'destroy']);\n\n $router->post('/instant-meeting/start', [InstantMeetingController::class, 'postRequestBotAtUrl'])\n ->middleware(['permission:' . PermissionEnum::RECORD_MEETING->value])\n ->name('instant-meeting.start');\n\n // Meeting creation endpoint for Outlook add-in\n $router->post('/meetings', [MeetingsController::class, 'create'])\n ->middleware(['permission:' . PermissionEnum::RECORD_MEETING->value])\n ->name('meetings.create');\n\n // Number provisioning and search.\n $router->get('/phone-numbers', [NumberAllocatorController::class, 'generate']);\n $router->get('/phone-numbers/{number}', [PhoneNumberController::class, 'number']);\n\n $router->group(['prefix' => 'deal-insights'], static function (Router $router): void {\n $router->get('/forecast', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'getForecast',\n ])->defaults('period', Forecast::PERIOD_QUARTER);\n\n $router->get('/deals/{stage?}', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'list',\n ])->defaults('stage', \\Jiminny\\Component\\DealInsights\\CriteriaInterface::STAGE_ALL);\n\n $router->get('/details/details-daily/{opportunityId}/{date}', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'detailsDaily',\n ]);\n\n $router->put('/deals/{opportunity}/edit-fields', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'updateFields',\n ]);\n\n $router->get('/externalId/{dealId}', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'externalDealId',\n ]);\n\n $router->put('/dealRisk/{dealRisk}', [DealRiskController::class, 'toggleActivity']);\n });\n\n $router->get('/team-insights/users', [TeamInsightsController::class, 'fetchUsers'])\n ->name('team_insights.users');\n\n $router->get('/team-insights/dashboard', [DashboardController::class, 'fetch'])\n ->name('team_insights.dashboard');\n\n // Team Insights - Coaching Feedbacks\n $router->get('/team-insights/coaching-feedbacks-over-time', [CoachingFeedbacksController::class, 'fetch'])\n ->name('team_insights.coaching_feedbacks_over_time');\n\n $router\n ->get('/team-insights/coaching-feedbacks-over-time/download', [CoachingFeedbacksController::class, 'download'])\n ->name('team_insights.coaching_feedbacks_over_time.download');\n\n $router->get(\n '/team-insights/coaching-feedbacks-over-time/drill-down',\n [CoachingFeedbacksController::class, 'drillDown'],\n )->name('team_insights.coaching_feedbacks_over_time.drill_down');\n\n // Team Insights - Automated Call Scores\n $router->get(\n '/team-insights/automated-call-scores-over-time',\n [TeamInsightsAutomatedCallScoresController::class, 'index'],\n )->name('team_insights.automated_call_scores_over_time.index');\n\n $router->get(\n '/team-insights/automated-call-scores-over-time/drill-down',\n [TeamInsightsAutomatedCallScoresController::class, 'show'],\n )->name('team_insights.automated_call_scores_over_time.show');\n\n // Team Insights - AI Call Scoring\n $router->get(\n '/team-insights/ai-call-scoring-over-time',\n [TeamInsightsAiCallScoringController::class, 'index'],\n )->name('team_insights.ai_call_scoring_over_time.index');\n\n $router->get(\n '/team-insights/ai-call-scoring-over-time/drill-down',\n [TeamInsightsAiCallScoringController::class, 'show'],\n )->name('team_insights.ai_call_scoring_over_time.show');\n\n $router->get('/team-insights/engagement', [ActivityStatsController::class, 'fetch'])\n ->name('team_insights.engagement');\n\n $router->get('/team-insights/engagement/drill-down/{engagementType}', [ActivityStatsController::class, 'drillDown'])\n ->name('team_insights.engagement.drill_down');\n\n $router->get('/team-insights/topics', [ThemeTopicsController::class, 'getTopics'])\n ->name('team_insights.topics.index');\n\n $router->get('/team-insights/topics/{topic}', [ThemeTopicsController::class, 'fetch'])\n ->name('team_insights.topics.show');\n\n $router->get('/team-insights/topics/{topic}/drill-down', [ThemeTopicsController::class, 'drillDown'])\n ->name('team_insights.topics.drill_down');\n\n $router->group(['prefix' => 'team-insights'], static function (Router $router): void {\n $router->group(['prefix' => 'conversations'], static function (Router $router): void {\n $router->get('/', [\n Controllers\\API\\TeamInsights\\ConversationsController::class,\n 'fetch',\n ]);\n\n $router->group(['prefix' => 'drill-down'], static function (Router $router): void {\n $router\n ->get('/{activityChannel}/{drillDownType}', [\n Controllers\\API\\TeamInsights\\ConversationsController::class,\n 'drillDown',\n ])\n ->where(\n 'activityChannel',\n Collection::make(Models\\Activity::CHANNELS)->join('|'),\n )\n ->where(\n 'drillDownType',\n Collection::make(Repositories\\TeamInsightsRepository::CONVERSATION_DRILLDOWNS)\n ->join('|'),\n );\n });\n });\n\n $router->group(['prefix' => 'coaching'], static function (Router $router): void {\n $router->get('/', [EngagementController::class, 'fetch']);\n\n $router->group(['prefix' => 'drill-down'], static function (Router $router): void {\n $router\n ->get('/{coachingType}/{drillDownType?}', [EngagementController::class, 'drillDown'])\n ->where(\n 'coachingType',\n Collection::make(EngagementController::COACHING_TYPES)->join('|'),\n )\n ->where(\n 'drillDownType',\n Collection::make(EngagementController::COACHING_DRILLDOWNS)->join('|'),\n );\n });\n });\n });\n\n $router->get('/topics-in-deals', [TopicsInDealsController::class, 'topics'])\n ->name('topics_in_deals.topics');\n $router->get('/topics-in-deals/topic-triggers', [TopicsInDealsController::class, 'topicTriggers'])\n ->name('topics_in_deals.topic_triggers');\n $router->get('/compare-topics-in-deals', [TopicsInDealsController::class, 'comparison'])\n ->name('topics_in_deals.comparison');\n\n // CRM actions.\n $router->group(['prefix' => 'crm'], static function (Router $router): void {\n $router->get('/search', [CrmController::class, 'search']);\n $router->get('/opportunity', [CrmController::class, 'opportunities']);\n $router->get('/customers', [CrmController::class, 'customers']);\n $router->get('/accounts', [CrmController::class, 'accounts']);\n $router->get('/contacts', [CrmController::class, 'contacts']);\n $router->get('/leads', [CrmController::class, 'leads']);\n $router->get('/tasks', [CrmController::class, 'activities']);\n $router->get('/layouts', [CrmController::class, 'layouts']);\n });\n\n // AI CRM notes.\n $router->group(['prefix' => 'ai-crm-notes'], static function (Router $router): void {\n $router->get('/activity/{activity}', [AiCrmNotesController::class, 'getByActivity']);\n $router->post('/activity/{activity}/log-to-crm', [AiCrmNotesController::class, 'logToCrmByActivity']);\n $router->post('/activity/{activity}/discard', [AiCrmNotesController::class, 'discardByActivity']);\n\n $router->get('/deal/{opportunity}', [AiCrmNotesController::class, 'getByOpportunity']);\n $router->post('/deal/{opportunity}/log-to-crm', [AiCrmNotesController::class, 'logToCrmByOpportunity']);\n $router->post('/deal/{opportunity}/discard', [AiCrmNotesController::class, 'discardByOpportunity']);\n });\n\n // Automated Reports\n $router->post('/automated-reports/interest', [UserAutomatedReportsController::class, 'trackInterest']);\n\n $router->group(\n [\n 'prefix' => 'automated-reports',\n 'middleware' => 'can:canAccessAiReports,' . User::class,\n ],\n static function (Router $router): void {\n $router->get('/', [UserAutomatedReportsController::class, 'list']);\n $router->delete('/{uuid}', [UserAutomatedReportsController::class, 'delete']);\n }\n );\n\n // Setup New Team / Trial\n $router->get('/features', [TeamSetupController::class, 'features']);\n $router->get('/tiers', [TeamSetupController::class, 'tiers']);\n $router->get('/calendars', [TeamSetupController::class, 'calendars']);\n $router->get('/crm-services', [TeamSetupController::class, 'crmServices']);\n $router->get('/connect-providers', [TeamSetupController::class, 'connectProviders']);\n $router->get('/integration-app-token', [TeamSetupController::class, 'integrationAppToken']);\n $router->post('/integration-app-connect', [TeamSetupController::class, 'integrationAppConnect']);\n\n // Notifications\n $router->get('/notifications/recent', [NotificationController::class, 'notifications']);\n $router->put('/notifications/read', [NotificationController::class, 'markAsRead']);\n $router->put('/notifications/read-multiple', [NotificationController::class, 'markMultipleAsRead']);\n $router->put('/notifications/read-all', [NotificationController::class, 'markAllAsRead']);\n\n // Live feed\n $router->get('/live-feed', [LiveFeedController::class, 'liveFeedItems']);\n\n // Languages\n $router->get('/languages', [LanguageController::class, 'list']);\n\n // The whole settings section will be moved out in a separate file\n $router->group(['prefix' => '/settings'], static function (Router $router): void {\n $router->group(['prefix' => '/organizations'], static function (Router $router): void {\n $router\n ->middleware(['can:kiosk,' . User::class])\n ->post('/', [OrganizationController::class, 'store'])\n ->name('kiosk.organizations.store');\n\n $router->group(['prefix' => '{team}', 'middleware' => ['teamMember']], static function (Router $router) {\n // Sync fields and team metadata\n $router->post('/fields/sync', [OrganizationSyncController::class, 'index'])\n ->name('api.sync.fields');\n\n // Conference Preferences.\n $router->post('/bot-avatar', [TeamPhotoController::class, 'updateBotAvatar'])\n ->name('update.bot.avatar');\n\n // Roles.\n $router->get('/roles', [OrganizationRolesController::class, 'index'])\n ->name('api.roles.index');\n\n $router->group(\n ['middleware' => 'permission:' . PermissionEnum::MANAGE_RETENTION_POLICY->value],\n static function (Router $router): void {\n $router->get('/retention-policy', [OrganizationRetentionPolicyController::class, 'index'])\n ->name('api.retention_policy.index');\n\n $router->post('/retention-policy', [OrganizationRetentionPolicyController::class, 'store'])\n ->name('api.retention_policy.update');\n }\n );\n\n $router->group(\n ['middleware' => 'permission:' . PermissionEnum::MANAGE_USERS->value],\n static function (Router $router): void {\n // Invitations.\n $router->get('/invitations', [InvitationController::class, 'index'])\n ->name('api.invitations.index');\n $router->post('/invitations/{invitation}', [InvitationController::class, 'resend'])\n ->name('api.invitations.resend');\n $router->delete('/invitations/{invitation}', [InvitationController::class, 'destroy'])\n ->name('api.invitations.delete');\n $router->post('/invitations', [InvitationController::class, 'store'])\n ->name('api.invitations.store');\n },\n );\n\n $router->group(\n ['middleware' => 'permission:' . PermissionEnum::MANAGE_TEAM->value],\n static function (Router $router): void {\n // Groups.\n $router->post('/groups', [GroupController::class, 'store']);\n $router->get('/groups/{group}', [GroupController::class, 'show']);\n $router->put('/groups/{group}', [GroupController::class, 'update']);\n\n $router->put('/group/{group}/scope', [GroupController::class, 'updateGroupScope']);\n\n $router->post('/group/{group}/dealRisks', [DealRiskController::class, 'updateSettings']);\n\n // Sidekick settings\n $router->group(\n ['middleware' => 'permission:' . PermissionEnum::MANAGE_SIDEKICK->value],\n static function (Router $router): void {\n $router->get('/sidekick', [SidekickController::class, 'getSidekickSettings']);\n $router\n ->post(\n '/group/{group}/sidekick',\n [SidekickController::class, 'setSidekickSettings'],\n )\n ->middleware(['can:updateSidekickSettings,group'])\n ->name('api.sidekick_settings.update');\n $router\n ->post('/sidekick', [SidekickController::class, 'setSidekickSettings'])\n ->middleware(['permission:' . PermissionEnum::UPDATE_ALL_SIDEKICK_SETTINGS->value])\n ->name('api.sidekick_settings.update_all');\n },\n );\n\n $router->get('/deal-insights', [TeamDealInsightsSettingController::class, 'index']);\n $router->patch('/deal-insights', [TeamDealInsightsSettingController::class, 'update']);\n\n // CRM Layout Management\n $router->group(['prefix' => 'layouts'], static function (Router $router): void {\n $router->get(\n '/{type}',\n [Controllers\\API\\LayoutManagementController::class, 'list'],\n )->name('layouts.list');\n\n $router->put(\n '/{layout}',\n [Controllers\\API\\LayoutManagementController::class, 'update'],\n )->name('layouts.update');\n });\n\n // Users.\n $router->put('/users/{user}', [TeamMemberController::class, 'update'])\n ->middleware(['permission:' . PermissionEnum::MANAGE_USERS->value])\n ->name('api.users.update');\n $router->delete('/users/{user}', [TeamMemberController::class, 'deactivate'])\n ->middleware(['permission:' . PermissionEnum::MANAGE_USERS->value])\n ->name('api.users.deactivate');\n\n $router->group(\n [\n 'prefix' => 'vocabulary',\n 'middleware' => 'can:manage,' . Vocabulary::class,\n ],\n static function (Router $router): void {\n $router\n ->get('/', [VocabularyController::class, 'list'])\n ->name('api.vocabulary.index');\n $router\n ->post('/', [VocabularyController::class, 'update'])\n ->name('api.vocabulary.create');\n\n $router->group(['prefix' => '{vocabulary}'], static function (Router $router): void {\n $router\n ->put('/', [VocabularyController::class, 'update'])\n ->middleware('can:update,vocabulary')\n ->name('api.vocabulary.update');\n $router\n ->delete('/', [VocabularyController::class, 'delete'])\n ->middleware('can:delete,vocabulary')\n ->name('api.vocabulary.delete');\n });\n },\n );\n\n $router->group(['prefix' => 'ai-context'], static function (Router $router): void {\n $router->get('/', [TeamAiContextController::class, 'index'])\n ->name('api.ai_context.get');\n $router->post('/', [TeamAiContextController::class, 'store'])\n ->name('api.ai_context.store');\n });\n\n $router->group(['prefix' => 'ai-automation'], static function (Router $router): void {\n $router->post('/fields/test-prompt', [TeamAiAutomationController::class, 'testCrmAiPrompt'])\n ->name('api.automation.templates.fields.test-prompt');\n // List CRM fields per object type\n $router->get('/fields/{objectType}', [TeamAiAutomationController::class, 'fields'])\n ->name('api.automation.fields');\n\n // List DealStages fields per object type\n $router->get('/stages', [TeamAiAutomationController::class, 'stages'])\n ->name('api.automation.stages');\n // Create CRM AI template\n $router->post('/templates', [TeamAiAutomationController::class, 'createTemplate'])\n ->name('api.automation.templates.create');\n\n // Export CRM updates\n $router->post('/templates/export-crm-updates', [TeamAiAutomationController::class, 'exportTemplateCrmUpdates'])\n ->name('api.automation.templates.export-crm-updates');\n\n // Update CRM AI template\n $router->put('/templates/{crmTemplate}', [TeamAiAutomationController::class, 'updateTemplate'])\n ->name('api.automation.templates.update');\n // Delete CRM AI template\n $router->delete('/templates/{crmTemplate}', [TeamAiAutomationController::class, 'deleteTemplate'])\n ->name('api.automation.templates.delete');\n // List all CRM AI templates\n $router->get('/templates', [TeamAiAutomationController::class, 'templates'])\n ->name('api.automation.templates.list');\n // Create CRM AI template field\n $router->post('/templates/{crmTemplate}/fields', [TeamAiAutomationController::class, 'createField'])\n ->name('api.automation.templates.fields.create');\n // Update CRM AI template field\n $router->put('/templates/{crmTemplate}/fields/{crmTemplateField}', [TeamAiAutomationController::class, 'updateField'])\n ->name('api.automation.templates.fields.update');\n // Delete CRM AI template field\n $router->delete('/templates/{crmTemplate}/fields/{crmTemplateField}', [TeamAiAutomationController::class, 'deleteField'])\n ->name('api.automation.templates.fields.delete');\n });\n\n $router->group(['prefix' => 'ai-call-scoring'], static function (Router $router): void {\n // Create AI scorecard\n $router->post('/ai-scorecards', [Controllers\\API\\AiCallScoring\\AiScorecardController::class, 'createAiScorecard'])\n ->name('api.ai-call-scoring.ai-scorecards.create');\n // Update AI scorecard\n $router->put('/ai-scorecards/{aiScorecard}', [Controllers\\API\\AiCallScoring\\AiScorecardController::class, 'updateAiScorecard'])\n ->name('api.ai-call-scoring.ai-scorecards.update');\n // Delete AI scorecard\n $router->delete('/ai-scorecards/{aiScorecard}', [Controllers\\API\\AiCallScoring\\AiScorecardController::class, 'deleteAiScorecard'])\n ->name('api.ai-call-scoring.ai-scorecards.delete');\n // Test AI scorecard prompt\n $router->post(\n '/ai-scorecards/{aiScorecard}/test-prompt',\n [\n Controllers\\API\\AiCallScoring\\AiScorecardController::class,\n 'testAiScorecardPrompt',\n ]\n )\n ->name('api.ai-call-scoring.ai-scorecards.test-prompt');\n\n // Create AI Scorecard rule\n $router->post('/ai-scorecards/{aiScorecard}/ai-scorecard-rules', [Controllers\\API\\AiCallScoring\\AiScorecardRuleController::class, 'createRule'])\n ->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.create');\n // Update AI Scorecard rule\n $router->put('/ai-scorecards/{aiScorecard}/ai-scorecard-rules/{aiScorecardRule}', [Controllers\\API\\AiCallScoring\\AiScorecardRuleController::class, 'updateAiScorecardRule'])\n ->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.update');\n // Delete AI Scorecard rule\n $router->delete('/ai-scorecards/{aiScorecard}/ai-scorecard-rules/{aiScorecardRule}', [Controllers\\API\\AiCallScoring\\AiScorecardRuleController::class, 'deleteAiScorecardRule'])\n ->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.delete');\n });\n\n // Theme, topics, triggers\n $router->get('/themes', [ThemeController::class, 'list']);\n $router\n ->post('/themes', [ThemeController::class, 'updateTheme'])\n ->middleware('can:manage,' . PlaybackTheme::class)\n ->name('api.theme.create');\n\n $router->group(\n [\n 'prefix' => 'theme/{theme}',\n 'middleware' => 'can:update,theme',\n ],\n static function (Router $router): void {\n $router\n ->put('/', [ThemeController::class, 'updateTheme'])\n ->name('api.theme.update');\n $router\n ->delete('/', [ThemeController::class, 'deleteTheme'])\n ->middleware('can:delete,theme')\n ->name('api.theme.delete');\n\n $router\n ->post('/topics', [TopicController::class, 'updateTopic'])\n ->middleware('can:createTopic,theme')\n ->name('api.topic.create');\n\n $router->group(\n [\n 'prefix' => 'topic/{topic}',\n 'middleware' => 'can:update,topic',\n ],\n static function (Router $router): void {\n $router\n ->put('/', [TopicController::class, 'updateTopic'])\n ->name('api.topic.update');\n $router\n ->delete('/', [TopicController::class, 'deleteTopic'])\n ->middleware('can:delete,topic')\n ->name('api.topic.delete');\n\n $router\n ->post('/triggers', [TopicTriggerController::class, 'updateTrigger'])\n ->middleware('can:createTrigger,topic')\n ->name('api.topic_trigger.create');\n\n $router->group(\n [\n 'prefix' => 'trigger/{topicTrigger}',\n 'middleware' => 'can:update,topicTrigger',\n ],\n static function (Router $router): void {\n $router\n ->put('/', [TopicTriggerController::class, 'updateTrigger'])\n ->name('api.topic_trigger.update');\n $router\n ->delete('/', [TopicTriggerController::class, 'deleteTrigger'])\n ->middleware('can:delete,topicTrigger')\n ->name('api.topic_trigger.delete');\n },\n );\n },\n );\n },\n );\n\n $router->post('/themes/import', [Controllers\\API\\Themes\\ImportTopicTriggerController::class, 'importThemes']);\n $router->get('/themes/export', [Controllers\\API\\Themes\\ExportTopicTriggerController::class, 'exportThemes']);\n\n // Auto-scoring\n $router->group(['prefix' => '/scorecards'], static function (Router $router) {\n $router->get('/', [Controllers\\API\\Scorecards\\ScorecardController::class, 'list']);\n $router->post('/', [Controllers\\API\\Scorecards\\ScorecardController::class, 'create']);\n $router->delete('/{scorecard}', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'delete',\n ]);\n $router->post('/validate-name', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'validateNameExists',\n ]);\n\n $router->get('/enabled-scorecard', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'getEnabledScorecard',\n ]);\n\n $router->get('/affected-scorecards', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'getAffectedScorecards',\n ]);\n\n $router->group(['prefix' => '/{scorecard}'], static function (Router $router) {\n $router->put('/', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'update',\n ]);\n $router->delete('/', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'delete',\n ]);\n\n $router->post('/rules', [\n Controllers\\API\\Scorecards\\ScorecardRuleController::class,\n 'create',\n ]);\n\n $router->post('/rules/{scorecardRule}', [\n Controllers\\API\\Scorecards\\ScorecardRuleController::class,\n 'update',\n ]);\n\n $router->delete('/rules/{scorecardRule}', [\n Controllers\\API\\Scorecards\\ScorecardRuleController::class,\n 'delete',\n ]);\n\n $router->post('/rules/{scorecardRule}/update-order', [\n Controllers\\API\\Scorecards\\ScorecardRuleController::class,\n 'updateOrder',\n ]);\n });\n });\n\n // Coaching Playbook.\n Route::get('/playbooks', [PlaybookController::class, 'all']);\n Route::get('/playbooksTree', [PlaybookController::class, 'tree']);\n Route::put('/playbooks/{playbook}', [PlaybookController::class, 'update']);\n Route::post('/playbooks', [PlaybookController::class, 'store']);\n Route::delete('/playbooks/{playbook}', [PlaybookController::class, 'destroy']);\n\n Route::prefix('/playbooks/{playbook}')->group(static function () {\n // Playbook Categories.\n Route::get('/categories', [PlaybookCategoryController::class, 'all']);\n Route::put('/categories/sequence', [PlaybookCategoryController::class, 'sequence']); // Respect order.\n Route::put('/categories/{category}', [PlaybookCategoryController::class, 'update']);\n Route::post('/categories', [PlaybookCategoryController::class, 'store']);\n Route::post('/test-prompt', [PlaybookController::class, 'testAiActivityTypePrompt']);\n Route::post('/prompt-suggestion', [PlaybookController::class, 'getPromptSuggestion']);\n Route::delete('/categories/{category}', [PlaybookCategoryController::class, 'destroy']);\n\n Route::prefix('/categories/{category}')->group(static function () {\n // Coaching Sections\n Route::get('/coaching-section', [Controllers\\Settings\\Coaching\\SectionsController::class, 'all']);\n Route::put('/coaching-section/sequence', [Controllers\\Settings\\Coaching\\SectionsController::class, 'sequence']);\n Route::put('/coaching-section/{coachingSection}', [Controllers\\Settings\\Coaching\\SectionsController::class, 'update']);\n Route::post('/coaching-section', [Controllers\\Settings\\Coaching\\SectionsController::class, 'store']);\n Route::delete('/coaching-section/{coachingSection}', [Controllers\\Settings\\Coaching\\SectionsController::class, 'destroy']);\n\n Route::prefix('coaching-section/{coachingSection}')->group(static function () {\n // Coaching Section Criteria\n Route::get('/coaching-section-criterion', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'all']);\n Route::put('/coaching-section-criterion/sequence', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'sequence']);\n Route::put('/coaching-section-criterion/{coachingSectionCriterion}', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'update']);\n Route::post('/coaching-section-criterion', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'store']);\n Route::delete('/coaching-section-criterion/{coachingSectionCriterion}', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'destroy']);\n });\n });\n });\n },\n );\n\n // List all AI scorecards (accessible to all team members, no MANAGE_TEAM required)\n $router->get('/ai-call-scoring/ai-scorecards', [Controllers\\API\\AiCallScoring\\AiScorecardController::class, 'aiScorecards'])\n ->name('api.ai-call-scoring.ai-scorecards.list');\n\n $router->middleware(['permission:' . PermissionEnum::MANAGE_ORGANIZATION_SETTINGS->value])\n ->group(static function (Router $router): void {\n // Job Titles.\n $router->get('/job-titles', [JobTitleController::class, 'all']);\n $router->put('/job-titles/{job}', [JobTitleController::class, 'update']);\n $router->post('/job-titles', [JobTitleController::class, 'store']);\n $router->delete('/job-titles/{job}', [JobTitleController::class, 'destroy']);\n\n // Team Settings.\n $router->put('/', [TeamSettingsController::class, 'update']);\n $router->put('/notifications', [TeamSettingsController::class, 'updateNotifications']);\n $router->put('/team-conference', [TeamConferenceSettingsController::class, 'update']);\n $router->put('/team-coaching', [TeamCoachingSettingsController::class, 'update']);\n $router->put('/team-softphone', [TeamSoftphoneSettingsController::class, 'update']);\n $router->put('/owner', [Controllers\\Settings\\Teams\\OrganizationSettingsController::class, 'updateOwner']);\n\n $router->put('/team-recording', [TeamRecordingSettingsController::class, 'update'])\n ->middleware(['permission:' . PermissionEnum::MANAGE_RECORDING->value]);\n\n // Key Moments.\n $router->get('/moments/{moment}', [Controllers\\Settings\\MomentController::class, 'show']);\n $router->put('/moments/{moment}', [Controllers\\Settings\\MomentController::class, 'update']);\n $router->post('/moments', [Controllers\\Settings\\MomentController::class, 'store']);\n $router->put('/activity', [TeamActivityController::class, 'store']);\n\n // Team Domains.\n $router->get('/domains', [Controllers\\Settings\\Teams\\TeamDomainsController::class, 'all']);\n $router->post('/domains', [Controllers\\Settings\\Teams\\TeamDomainsController::class, 'create']);\n $router->delete('/domains/{teamDomain}', [Controllers\\Settings\\Teams\\TeamDomainsController::class, 'destroy']);\n });\n });\n });\n });\n\n // Integrations\n $router->group(['middleware' => 'permission:' . PermissionEnum::MANAGE_INTEGRATIONS->value], static function (Router $router): void {\n $router->post('/integrations', [IntegrationController::class, 'internal'])\n ->name('api.integrations.internal');\n $router->put('/integrations', [IntegrationController::class, 'toggleStatus'])\n ->name('api.integrations.toggle_status');\n $router->delete('/integrations/{provider}', [IntegrationController::class, 'delete'])\n ->name('api.integrations.delete');\n });\n\n $router->get('/integrations', [IntegrationController::class, 'all'])\n ->middleware('permission:' . PermissionEnum::READ_INTEGRATIONS->value)\n ->name('api.integrations.index');\n\n // Slack API for getting slack channels list\n $router->get('{notificationProvider}/channels', [Controllers\\NotificationProviderController::class, 'channels']);\n\n\n // Team actions. XXX: These all need moving out to their own controllers.\n $router->group(['prefix' => 'organizations'], static function (Router $router): void {\n $router->get('current', [TeamController::class, 'current']);\n\n $router->group(['prefix' => '{team}', 'middleware' => ['teamMember']], static function (Router $router): void {\n $router->get('/', [TeamController::class, 'show']);\n\n $router->get('/categories', [TeamController::class, 'categories']);\n $router->get('/stages', [TeamController::class, 'stages']);\n $router->get('/users', [OrganizationMembersController::class, 'index'])\n ->name('organization.members.index');\n $router\n ->get('/users/download', [OrganizationMembersController::class, 'download'])\n ->middleware('permission:' . PermissionEnum::MANAGE_USERS->value)\n ->name('organization.members.download');\n $router->get('/licensed-roles', [OrganizationLicensesController::class, 'index'])\n ->middleware('permission:' . PermissionEnum::MANAGE_BILLING->value)\n ->name('organization.licensed-roles.index');\n $router->get('/invitations', [TeamController::class, 'invitations']);\n $router->get('/groups', [TeamController::class, 'groups']);\n $router->delete('/groups/{group}', [TeamController::class, 'deleteGroup'])\n ->middleware(['permission:' . PermissionEnum::DELETE_TEAM->value])\n ->name('api.groups.delete');\n $router->get('/job-titles', [TeamController::class, 'jobTitles']);\n $router->get('/slugs', [TeamController::class, 'slugs']);\n $router->put('/api-token', [TeamController::class, 'generateApiToken'])\n ->middleware(['permission:' . PermissionEnum::MANAGE_ORGANIZATION_SETTINGS->value]);\n $router->get('/key-moments', [MomentController::class, 'all']);\n });\n });\n\n // Internal Kiosk. This whole section will be moved out to a separate file\n $router\n ->prefix('kiosk')\n ->middleware('can:kiosk,' . User::class)\n ->group(static function (Router $router): void {\n // Partner actions.\n $router->get('/partners', [PartnersController::class, 'index']);\n\n // User actions.\n $router->post('/users/search', [SearchController::class, 'performBasicSearch']);\n\n // Team actions.\n $router->prefix('organizations')->group(static function (Router $router): void {\n $router->get('/', [OrganizationsController::class, 'show']);\n $router->put('/{team}', [OrganizationController::class, 'edit'])\n ->name('kiosk.organizations.edit');\n $router->get('/{team}/users', [OrganizationMembersController::class, 'index'])\n ->name('kiosk.organization.members.index');\n $router->get('onboardable', [OnboardController::class, 'available']);\n $router->delete('/{team}', [OrganizationsController::class, 'deactivateAccounts']);\n });\n\n // Automated reports\n // api/v1/kiosk/automated-reports\n $router->prefix('automated-reports')->group(static function (Router $router): void {\n $router->get('/form-data', [AutomatedReportsController::class, 'getCreateForm']);\n $router->get('/form-data/{reportUuid}', [AutomatedReportsController::class, 'getEditForm']);\n $router->post('/filters', [AutomatedReportsController::class, 'getFilters']);\n $router->post('/', [AutomatedReportsController::class, 'create']);\n $router->put('/{reportUuid}', [AutomatedReportsController::class, 'update']);\n $router->patch('/{reportUuid}', [AutomatedReportsController::class, 'partialUpdate']);\n $router->get('/', [AutomatedReportsController::class, 'list']);\n $router->get('/{reportUuid}', [AutomatedReportsController::class, 'get']);\n $router->delete('/{reportUuid}', [AutomatedReportsController::class, 'delete']);\n $router->post('/activities-count', [AutomatedReportsController::class, 'getActivitiesCount']);\n $router->get('/{reportUuid}/reports-count', [AutomatedReportsController::class, 'getReportsCount']);\n });\n\n // Activity actions.\n $router->post('/activity/search', [SearchController::class, 'performActivitySearch']);\n $router->prefix('activity/{activity}')->group(static function (Router $router): void {\n $router->post('check-playable', [SearchController::class, 'performActivityCheckPlayable']);\n $router->post('reset-crm-log', [SearchController::class, 'performResetCrmLogActivity']);\n $router->get('diarize-via-transcript', [KioskActivityController::class, 'diarizeViaTranscript']);\n $router->post('diarize-via-transcript', [KioskActivityController::class, 'diarizeViaTranscript']);\n $router->get('media-pipeline', [MediaPipelineController::class, 'getPipes']);\n $router->post('media-pipeline', [MediaPipelineController::class, 'updatePipe']);\n $router->post('language', [KioskActivityController::class, 'updateLanguage']);\n $router->post('trim', [KioskActivityController::class, 'trimActivity']);\n $router->get('troubleshoot', [KioskActivityController::class, 'troubleshootActivity']);\n $router->get('transcription', [KioskActivityController::class, 'getTranscriptions']);\n $router->post('speakers', [KioskActivityController::class, 'addSpeakers']);\n $router->post('crm-fields-fill', [KioskActivityController::class, 'crmFieldsFill']);\n $router->post('summary-highlights', [KioskActivityController::class, 'summaryHighlights']);\n });\n });\n});\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->group(['prefix' => 'events'], static function (Router $router): void {\n $router->post('authenticate', [Controllers\\PusherController::class, 'auth'])\n ->name(Routes::WEBHOOK_PUSHER_AUTH);\n });\n});\n\n$router->group(['middleware' => ['api']], static function (Router $router): void {\n $router->get('/extensions/auth', [ExtensionController::class, 'authenticate']);\n $router->get('/call-token/{team}/{participant?}', [ClientTokenController::class, 'generateToken']);\n});\n\n$router->group(['prefix' => 'user'], static function (Router $router): void {\n $router->get('chrome-extension-authentication', [ExtensionController::class, 'authenticate']);\n});\n\n$router->group(['middleware' => ['auth:api'], 'prefix' => 'sms'], static function (Router $router): void {\n $router->get('/{phoneNumber}', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'messages']);\n $router->get('/', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'messagesList']);\n $router->post('/', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'send']);\n $router->delete('/{activity}', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'redact']);\n $router->put('/{activity}', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'resend']);\n});\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/users/current', [UserController::class, 'current']);\n\n $router->get('/users/slug/{slug?}', [UserController::class, 'validateSlug']);\n\n // Profile Contact Information.\n $router->put(\n '/users/{user}/settings/profile',\n [Controllers\\Settings\\Profile\\ContactInformationController::class, 'update'],\n );\n\n $router->get('/users/{user}/email-sync-settings', [EmailSyncController::class, 'index']);\n $router->put('/users/{user}/email-sync-settings', [EmailSyncController::class, 'update']);\n\n // SMS Settings.\n $router->put('/users/{user}/settings/sms', [Controllers\\Settings\\Profile\\SmsController::class, 'update']);\n\n $router->get('/settings/timezones', [Controllers\\API\\Settings\\TimeZoneController::class, 'index'])\n ->name('settings.timezones.index');\n\n $router->put('/settings/user/deal-insights', [Controllers\\Settings\\Users\\UserSettingsController::class, 'update']);\n});\n\n$router->group(['prefix' => 'page', 'middleware' => ['api', 'auth:api']], static function () use ($router): void {\n $router->get('/playback/{activity}', [PlaybackController::class, 'show'])\n ->name('api.playback');\n $router->get('/on-demand', [OnDemandController::class, 'show'])\n ->name('api.activity.search');\n});\n\n$router->group(['prefix' => 'partners', 'middleware' => 'auth:partner-api'], static function () use ($router): void {\n $router->get('/', [PartnerController::class, 'me']);\n\n $router->group(['prefix' => 'organizations'], static function () use ($router): void {\n $router->get('/{team}', [PartnerController::class, 'fetchOrganization']);\n $router->post('/', [PartnerController::class, 'createOrganization']);\n });\n\n $router->group(['prefix' => 'groups'], static function () use ($router): void {\n $router->get('/{group}', [PartnerController::class, 'fetchGroup']);\n $router->post('/', [PartnerController::class, 'createGroup']);\n });\n\n $router->group(['prefix' => 'users'], static function () use ($router): void {\n $router->get('/{user}', [PartnerController::class, 'fetchUser']);\n $router->post('/', [PartnerController::class, 'createUser']);\n $router->delete('/{user}', [PartnerController::class, 'deactivateUser']);\n });\n\n $router->group(['prefix' => 'activities'], static function () use ($router): void {\n $router->get('/{activity}', [PartnerController::class, 'fetchActivity']);\n $router->get('/', [PartnerController::class, 'searchActivity']);\n });\n});\n\n$router->group(['prefix' => 'activity', 'middleware' => 'api'], static function () use ($router): void {\n // User only.\n $router->group(['middleware' => ['auth:api']], static function () use ($router): void {\n // Bulk delete\n $router->delete('/', [ActivityController::class, 'delete']);\n\n // Search.\n $router->get('/search', [ActivityController::class, 'search']);\n\n // All comments.\n $router->get('/comments', [ActivityController::class, 'fetchComments']);\n\n // Transcription AI\n $router->get('/{activity}/action-items', [Controllers\\API\\ActionItemsController::class, 'index']);\n $router->get('/{activity}/ai-call-scoring', [Controllers\\API\\AiCallScoring\\AiCallScoringController::class, 'index']);\n\n $router->get('/saved-search', [ActivityController::class, 'listActivitySearch'])->name('api.saved_search.index');\n $router->get('/saved-search/{search}', [ActivityController::class, 'fetchActivitySearch'])->name('api.saved_search.show');\n $router->post('/saved-search', [ActivityController::class, 'createActivitySearch'])->name('api.saved_search.create');\n $router->put('/saved-search/{search}', [ActivityController::class, 'updateActivitySearch'])->name('api.saved_search.update');\n $router->delete('/saved-search/{search}', [ActivityController::class, 'deleteActivitySearch'])->name('api.saved_search.delete');\n\n $router->post('/saved-search/{search}/nudges', [NudgeController::class, 'createAction'])->name('api.nudges.create');\n $router->put('/saved-search/{search}/nudges/{nudge}', [NudgeController::class, 'updateAction'])->name('api.nudges.update');\n $router->delete('/saved-search/{search}/nudges/{nudge}', [NudgeController::class, 'deleteAction'])->name('api.nudges.delete');\n\n // Live (coaching).\n $router->get('/live', [ActivityController::class, 'live']);\n $router->get('/{activity}/cloudfront-s3-media-keys', [ActivityController::class, 'fetchCloudFrontS3MediaKeys']);\n\n $router->post('/softphone', [SoftphoneController::class, 'create']);\n $router->put('/softphone', [SoftphoneController::class, 'createCoachParticipant']);\n $router->post('/softphone/dial', [SoftphoneController::class, 'dial']);\n $router->get('/softphone/{activity}', [SoftphoneController::class, 'fetch']);\n $router->delete('/softphone/{activity}', [SoftphoneController::class, 'endCall']);\n\n $router->post('softphone/{activity}/message', [SoftphoneController::class, 'message']);\n });\n\n // Activity actions.\n $router->group(['prefix' => '{activity}', 'middleware' => ['auth:api']], static function (Router $router): void {\n // User only.\n $router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n // Messages endpoint.\n $router->post('/message', [MessageController::class, 'message']);\n\n // Organizer actions.\n $router->put('/', [ActivityController::class, 'update']);\n $router->get('/', [ActivityController::class, 'show']);\n $router->delete('/', [ActivityController::class, 'destroy']);\n\n $router->post('/recording', [ActivityController::class, 'createRecording']);\n $router->put('/recording', [ActivityController::class, 'updateRecording']);\n $router->delete('/recording', [ActivityController::class, 'stopRecording']);\n\n $router->post('/summarize', [ActivityController::class, 'summarize']);\n\n // Sales Activity Playback action.\n $router->put('/favorite', [ActivityController::class, 'favorite']);\n $router->delete('/favorite', [ActivityController::class, 'unfavorite']);\n\n $router->put('/private', [ActivityController::class, 'markAsPrivate']);\n $router->delete('/private', [ActivityController::class, 'markAsPublic']);\n\n $router->put('/notification', [ActivityController::class, 'notify']);\n $router->delete('/notification/{notification}', [ActivityController::class, 'unnotify']);\n\n // Activity comments\n $router->put('/comment/{comment}', [ActivityController::class, 'updateComment']);\n $router->post('/comment/{comment}', [ActivityController::class, 'replyComment']);\n $router->post('/comment', [ActivityController::class, 'comment']);\n $router->delete('/comment/{comment}', [ActivityController::class, 'deleteComment']);\n $router->put('/comment/{comment}/visibility', [ActivityController::class, 'updateCommentVisibility']);\n\n $router->get('/coaching-sections', [ActivityController::class, 'coachingSections']);\n\n $router->put('/coach', [ActivityController::class, 'putCoachingFeedback']);\n $router->delete('/coach/{coachingFeedback}', [ActivityController::class, 'deleteCoachingFeedback']);\n\n $router->post('/coach-request', [ActivityController::class, 'coachRequest']);\n $router->post('/share', [ActivityController::class, 'share']);\n\n $router->post('/playlists', [ActivityController::class, 'addToPlaylist'])\n ->name('playlists.add.activity');\n\n $router->post('/key-moment', [MomentController::class, 'store']);\n\n $router->put('/play', [ActivityController::class, 'play']);\n\n $router->get('/stats', [ActivityController::class, 'stats']);\n\n $router->get('/topic-triggers', [ActivityController::class, 'fetchActivityTopicTriggers']);\n\n $router->post('/topic-triggers', [ActivityController::class, 'createActivityTopicTriggers']);\n\n $router->get('/auto-score', [Controllers\\API\\Scorecards\\AutoScoreController::class, 'getAutoScore']);\n $router->post('/auto-score', [Controllers\\API\\Scorecards\\AutoScoreController::class, 'updateAutoScore']);\n\n // Get Download link for an activity\n $router->get('/download', [Controllers\\PlaybackController::class, 'getDownloadUrl'])->name('getDownloadUrl');\n\n $router->post('/note', [ActivityController::class, 'note']);\n\n $router->post('/export', [ExportController::class, 'share'])\n ->middleware(['throttle:activity-export']);\n\n $router->post('/shareable-link', [ExportController::class, 'getShareableLink'])\n ->middleware(['throttle:activity-export-shareable-link']);\n\n $router->group(['prefix' => 'transcription'], static function (Router $router): void {\n $router->get('/', [TranscriptionController::class, 'getTranscriptionByActivity']);\n $router->get('/search', [TranscriptionController::class, 'searchAction']);\n $router->get('/download', [TranscriptionController::class, 'downloadTranscriptionByActivity'])\n ->middleware(['throttle:transcription-download']);\n $router->put('/attribution-flip/{participantA}/{participantB}', [Controllers\\API\\TranscriptionController::class, 'speakerAttributionFlip']);\n $router->put('/attribution-change/{participant}', [Controllers\\API\\TranscriptionController::class, 'speakerAttributionChange']);\n $router->get('/translation', [TranslationController::class, 'getTranslation']);\n });\n });\n });\n});\n\n$router->group(['middleware' => ['auth:api']], static function () use ($router) {\n $router->put('/subscription/{morphType}', [SubscriptionController::class, 'subscribe']);\n $router->delete('/subscription/{morphType}', [SubscriptionController::class, 'unsubscribe']);\n});\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/playlists', [PlaylistController::class, 'all'])->name('api.playlists.all');\n $router->get('/playlists/user', [PlaylistController::class, 'userPlaylists'])\n ->name('api.playlists.userPlaylists');\n $router->post('/playlists', [PlaylistController::class, 'store'])->name('api.playlists.store');\n\n $router->post('/playlists/{playlist}/share', [PlaylistController::class, 'share'])\n ->name('api.playlist.create.share');\n $router->get('/playlists/{playlist}/activities', [PlaylistController::class, 'activities'])\n ->name('api.playlist.activities');\n $router->delete('/playlists/{playlist}/shares/{playlistShare}', [PlaylistController::class, 'unshare'])\n ->name('api.playlist.unshare');\n $router->get('/playlists/{playlist}/shares', [PlaylistController::class, 'shares'])\n ->name('api.playlist.get.shares');\n $router->post('/playlists/{playlist}/lock', [PlaylistController::class, 'lock'])->name('api.playlist.lock');\n $router->post('/playlists/{playlist}/unlock', [PlaylistController::class, 'unlock'])\n ->name('api.playlist.unlock');\n $router->get(\n '/playlists/{playlist}/available-playlists',\n [PlaylistController::class, 'availablePlaylistsToMoveTo'],\n )->name('api.playlist.available');\n $router->put('/playlists/{playlist}', [PlaylistController::class, 'update'])->name('api.playlist.update');\n $router->delete('/playlists/{playlist}', [PlaylistController::class, 'destroy'])\n ->name('api.playlist.destroy');\n $router->put(\n '/playlists/{playlist}/tracks/{playlistActivity}',\n [PlaylistController::class, 'updatePlaylistTrack'],\n )->name('api.playlist.updatePlaylistTrack');\n $router->put(\n '/playlists/{playlist}/tracks/{playlistActivity}/move',\n [PlaylistController::class, 'moveToPlaylist'],\n )->name('api.playlist.moveToPlaylist');\n $router->delete(\n '/playlists/{playlist}/tracks/{playlistActivity}',\n [PlaylistController::class, 'removeFromPlaylist'],\n )->name('api.playlist.removeFromPlaylist');\n});\n\n$router->group(\n ['prefix' => '/opportunity/{opportunity}', 'middleware' => ['api']],\n static function (Router $router): void {\n // Opportunity comments\n $router->group(['prefix' => '/comment', 'middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/', [CommentsController::class, 'fetchComments']);\n $router->post('/', [CommentsController::class, 'comment']);\n\n $router->group(['prefix' => '{comment}'], static function (Router $router): void {\n $router->put('/', [CommentsController::class, 'updateComment']);\n $router->post('/', [CommentsController::class, 'replyComment']);\n $router->delete('/', [CommentsController::class, 'deleteComment']);\n $router->put('/visibility', [CommentsController::class, 'updateCommentVisibility']);\n });\n });\n },\n);\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/playlist/{activity}.m3u8', [Controllers\\API\\PlaybackController::class, 'playlist']);\n $router->get('/media/{track}.m3u8', [Controllers\\API\\PlaybackController::class, 'media']);\n});\n\n$router->group(['middleware' => ['api']], static function (Router $router): void {\n // SSO email query.\n $router->get('/auth/sso/login', [Controllers\\API\\SsoController::class, 'ssoLogin'])->name('ssoLogin');\n});\n\n$router->get('/mobile-settings', [MobileSettingsController::class, 'getAll']);\n\n$router->put('/mobile-settings', [MobileSettingsController::class, 'updateSettings'])\n ->middleware(['auth:api', 'can:kiosk,' . User::class])\n ->name('api.kiosk.mobile_settings.update');\n\n// Ask Jiminny on deal level\n$router->get('deals/{opportunity}/ask-jiminny', [Controllers\\API\\DealLevelPromptsController::class, 'index'])\n ->middleware(['api', 'auth:api'])\n ->name('api.deals.ask-jiminny');\n\n$router->get('get-access-token/{provider?}', [SocialController::class, 'getAccessToken'])\n ->name('api.get_access_token')\n ->whereIn('provider', [SocialAccount::PROVIDER_HUBSPOT]);\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->post('single-claim-token/{provider?}', [SocialController::class, 'getSingleUseClaim'])\n ->name('api.singe-claim-token');\n});\n\n$router->post('deauthorize-zoom-app', [SocialController::class, 'deauthorizeZoomApp'])\n ->name('api.deauthorize-zoom-app.recall-ai');\n\n$router->put('/conferences/{activity}/consent', [ConferencesOptInOutController::class, 'storeConsent'])\n ->middleware(['throttle:conference-consent'])\n ->name('api.conferences.store-consent');","depth":4,"bounds":{"left":0.13863032,"top":0.09736632,"width":0.37832448,"height":0.90263367},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\n/**\n * API routes.\n *\n * @see \\Jiminny\\Providers\\RouteServiceProvider\n *\n * @var Router $router\n */\n\nuse Illuminate\\Routing\\Router;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\DealInsights\\Forecast\\Forecast;\nuse Jiminny\\Component\\Router\\Routes;\nuse Jiminny\\Contracts\\Acl\\PermissionEnum;\nuse Jiminny\\Http\\Controllers;\nuse Jiminny\\Http\\Controllers\\API\\ActivityController;\nuse Jiminny\\Http\\Controllers\\API\\AiCrmNotesController;\nuse Jiminny\\Http\\Controllers\\API\\ClientTokenController;\nuse Jiminny\\Http\\Controllers\\API\\CrmController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\TeamInsightsAiCallScoringController;\nuse Jiminny\\Http\\Controllers\\ConferencesOptInOutController;\nuse Jiminny\\Http\\Controllers\\API\\DealRiskController;\nuse Jiminny\\Http\\Controllers\\API\\InstantMeetingController;\nuse Jiminny\\Http\\Controllers\\API\\LanguageController;\nuse Jiminny\\Http\\Controllers\\API\\LiveFeedController;\nuse Jiminny\\Http\\Controllers\\API\\MeetingsController;\nuse Jiminny\\Http\\Controllers\\API\\MessageController;\nuse Jiminny\\Http\\Controllers\\API\\MetadataController;\nuse Jiminny\\Http\\Controllers\\API\\MobileSettingsController;\nuse Jiminny\\Http\\Controllers\\API\\MomentController;\nuse Jiminny\\Http\\Controllers\\API\\NudgeController;\nuse Jiminny\\Http\\Controllers\\API\\NumberAllocatorController;\nuse Jiminny\\Http\\Controllers\\API\\Opportunity\\CommentsController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationLicensesController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationMembersController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationRetentionPolicyController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationRolesController;\nuse Jiminny\\Http\\Controllers\\API\\OrganizationSyncController;\nuse Jiminny\\Http\\Controllers\\API\\Page\\OnDemandController;\nuse Jiminny\\Http\\Controllers\\API\\Page\\PlaybackController;\nuse Jiminny\\Http\\Controllers\\API\\PartnerController;\nuse Jiminny\\Http\\Controllers\\API\\PhoneNumberController;\nuse Jiminny\\Http\\Controllers\\API\\PlaylistController;\nuse Jiminny\\Http\\Controllers\\API\\Settings\\EmailSyncController;\nuse Jiminny\\Http\\Controllers\\API\\SidekickController;\nuse Jiminny\\Http\\Controllers\\API\\SoftphoneController;\nuse Jiminny\\Http\\Controllers\\API\\SubscriptionController;\nuse Jiminny\\Http\\Controllers\\API\\TeamAiAutomationController;\nuse Jiminny\\Http\\Controllers\\API\\TeamAiContextController;\nuse Jiminny\\Http\\Controllers\\API\\TeamController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\ActivityStatsController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\CoachingFeedbacksController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\DashboardController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\EngagementController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\TeamInsightsAutomatedCallScoresController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\ThemeTopicsController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsights\\TopicsInDealsController;\nuse Jiminny\\Http\\Controllers\\API\\TeamInsightsController;\nuse Jiminny\\Http\\Controllers\\API\\Themes\\ThemeController;\nuse Jiminny\\Http\\Controllers\\API\\Themes\\TopicController;\nuse Jiminny\\Http\\Controllers\\API\\Themes\\TopicTriggerController;\nuse Jiminny\\Http\\Controllers\\API\\TranscriptionController;\nuse Jiminny\\Http\\Controllers\\API\\TranslationController;\nuse Jiminny\\Http\\Controllers\\API\\UserAutomatedReports\\UserAutomatedReportsController;\nuse Jiminny\\Http\\Controllers\\API\\UserController;\nuse Jiminny\\Http\\Controllers\\API\\VocabularyController;\nuse Jiminny\\Http\\Controllers\\Auth\\ExtensionController;\nuse Jiminny\\Http\\Controllers\\Auth\\SocialController;\nuse Jiminny\\Http\\Controllers\\ExportController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\ActivityController as KioskActivityController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\AutomatedReportsController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\MediaPipelineController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\OrganizationsController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\PartnersController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\SearchController;\nuse Jiminny\\Http\\Controllers\\Kiosk\\Teams\\OnboardController;\nuse Jiminny\\Http\\Controllers\\NotificationController;\nuse Jiminny\\Http\\Controllers\\Settings\\GroupController;\nuse Jiminny\\Http\\Controllers\\Settings\\JobTitleController;\nuse Jiminny\\Http\\Controllers\\Settings\\PlaybookCategoryController;\nuse Jiminny\\Http\\Controllers\\Settings\\PlaybookController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\IntegrationController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\InvitationController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamActivityController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamCoachingSettingsController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamConferenceSettingsController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamController as OrganizationController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamDealInsightsSettingController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamMemberController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamPhotoController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamRecordingSettingsController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamSettingsController;\nuse Jiminny\\Http\\Controllers\\Settings\\Teams\\TeamSoftphoneSettingsController;\nuse Jiminny\\Http\\Controllers\\TeamSetupController;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\PlaybackTheme;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models\\Vocabulary;\nuse Jiminny\\Repositories;\nuse Jiminny\\Mcp\\Servers\\JiminnyServer;\nuse Laravel\\Mcp\\Facades\\Mcp;\n\n// mcp.audit MUST stay outermost so its $next($request) call wraps the auth\n// and tier guards. Otherwise 401 (auth:api) and 403 (mcp.tier) rejections\n// short-circuit before McpAuditMiddleware::handle ever runs and we lose\n// audit rows for exactly the requests the security log most needs to capture.\n// McpAuditMiddleware::writeAuditRow null-checks $request->user(), so writing\n// pre-auth is safe.\nMcp::web('/mcp', JiminnyServer::class)\n ->middleware(['mcp.audit', 'auth:api', 'mcp.tier']);\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/metadata/extension-app', [MetadataController::class, 'extension']);\n\n $router->get('/', [NumberAllocatorController::class, 'generate']);\n $router->delete('/key-moment/{activityMoment}', [MomentController::class, 'destroy']);\n\n $router->post('/instant-meeting/start', [InstantMeetingController::class, 'postRequestBotAtUrl'])\n ->middleware(['permission:' . PermissionEnum::RECORD_MEETING->value])\n ->name('instant-meeting.start');\n\n // Meeting creation endpoint for Outlook add-in\n $router->post('/meetings', [MeetingsController::class, 'create'])\n ->middleware(['permission:' . PermissionEnum::RECORD_MEETING->value])\n ->name('meetings.create');\n\n // Number provisioning and search.\n $router->get('/phone-numbers', [NumberAllocatorController::class, 'generate']);\n $router->get('/phone-numbers/{number}', [PhoneNumberController::class, 'number']);\n\n $router->group(['prefix' => 'deal-insights'], static function (Router $router): void {\n $router->get('/forecast', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'getForecast',\n ])->defaults('period', Forecast::PERIOD_QUARTER);\n\n $router->get('/deals/{stage?}', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'list',\n ])->defaults('stage', \\Jiminny\\Component\\DealInsights\\CriteriaInterface::STAGE_ALL);\n\n $router->get('/details/details-daily/{opportunityId}/{date}', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'detailsDaily',\n ]);\n\n $router->put('/deals/{opportunity}/edit-fields', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'updateFields',\n ]);\n\n $router->get('/externalId/{dealId}', [\n Controllers\\API\\DealInsights\\DealsController::class,\n 'externalDealId',\n ]);\n\n $router->put('/dealRisk/{dealRisk}', [DealRiskController::class, 'toggleActivity']);\n });\n\n $router->get('/team-insights/users', [TeamInsightsController::class, 'fetchUsers'])\n ->name('team_insights.users');\n\n $router->get('/team-insights/dashboard', [DashboardController::class, 'fetch'])\n ->name('team_insights.dashboard');\n\n // Team Insights - Coaching Feedbacks\n $router->get('/team-insights/coaching-feedbacks-over-time', [CoachingFeedbacksController::class, 'fetch'])\n ->name('team_insights.coaching_feedbacks_over_time');\n\n $router\n ->get('/team-insights/coaching-feedbacks-over-time/download', [CoachingFeedbacksController::class, 'download'])\n ->name('team_insights.coaching_feedbacks_over_time.download');\n\n $router->get(\n '/team-insights/coaching-feedbacks-over-time/drill-down',\n [CoachingFeedbacksController::class, 'drillDown'],\n )->name('team_insights.coaching_feedbacks_over_time.drill_down');\n\n // Team Insights - Automated Call Scores\n $router->get(\n '/team-insights/automated-call-scores-over-time',\n [TeamInsightsAutomatedCallScoresController::class, 'index'],\n )->name('team_insights.automated_call_scores_over_time.index');\n\n $router->get(\n '/team-insights/automated-call-scores-over-time/drill-down',\n [TeamInsightsAutomatedCallScoresController::class, 'show'],\n )->name('team_insights.automated_call_scores_over_time.show');\n\n // Team Insights - AI Call Scoring\n $router->get(\n '/team-insights/ai-call-scoring-over-time',\n [TeamInsightsAiCallScoringController::class, 'index'],\n )->name('team_insights.ai_call_scoring_over_time.index');\n\n $router->get(\n '/team-insights/ai-call-scoring-over-time/drill-down',\n [TeamInsightsAiCallScoringController::class, 'show'],\n )->name('team_insights.ai_call_scoring_over_time.show');\n\n $router->get('/team-insights/engagement', [ActivityStatsController::class, 'fetch'])\n ->name('team_insights.engagement');\n\n $router->get('/team-insights/engagement/drill-down/{engagementType}', [ActivityStatsController::class, 'drillDown'])\n ->name('team_insights.engagement.drill_down');\n\n $router->get('/team-insights/topics', [ThemeTopicsController::class, 'getTopics'])\n ->name('team_insights.topics.index');\n\n $router->get('/team-insights/topics/{topic}', [ThemeTopicsController::class, 'fetch'])\n ->name('team_insights.topics.show');\n\n $router->get('/team-insights/topics/{topic}/drill-down', [ThemeTopicsController::class, 'drillDown'])\n ->name('team_insights.topics.drill_down');\n\n $router->group(['prefix' => 'team-insights'], static function (Router $router): void {\n $router->group(['prefix' => 'conversations'], static function (Router $router): void {\n $router->get('/', [\n Controllers\\API\\TeamInsights\\ConversationsController::class,\n 'fetch',\n ]);\n\n $router->group(['prefix' => 'drill-down'], static function (Router $router): void {\n $router\n ->get('/{activityChannel}/{drillDownType}', [\n Controllers\\API\\TeamInsights\\ConversationsController::class,\n 'drillDown',\n ])\n ->where(\n 'activityChannel',\n Collection::make(Models\\Activity::CHANNELS)->join('|'),\n )\n ->where(\n 'drillDownType',\n Collection::make(Repositories\\TeamInsightsRepository::CONVERSATION_DRILLDOWNS)\n ->join('|'),\n );\n });\n });\n\n $router->group(['prefix' => 'coaching'], static function (Router $router): void {\n $router->get('/', [EngagementController::class, 'fetch']);\n\n $router->group(['prefix' => 'drill-down'], static function (Router $router): void {\n $router\n ->get('/{coachingType}/{drillDownType?}', [EngagementController::class, 'drillDown'])\n ->where(\n 'coachingType',\n Collection::make(EngagementController::COACHING_TYPES)->join('|'),\n )\n ->where(\n 'drillDownType',\n Collection::make(EngagementController::COACHING_DRILLDOWNS)->join('|'),\n );\n });\n });\n });\n\n $router->get('/topics-in-deals', [TopicsInDealsController::class, 'topics'])\n ->name('topics_in_deals.topics');\n $router->get('/topics-in-deals/topic-triggers', [TopicsInDealsController::class, 'topicTriggers'])\n ->name('topics_in_deals.topic_triggers');\n $router->get('/compare-topics-in-deals', [TopicsInDealsController::class, 'comparison'])\n ->name('topics_in_deals.comparison');\n\n // CRM actions.\n $router->group(['prefix' => 'crm'], static function (Router $router): void {\n $router->get('/search', [CrmController::class, 'search']);\n $router->get('/opportunity', [CrmController::class, 'opportunities']);\n $router->get('/customers', [CrmController::class, 'customers']);\n $router->get('/accounts', [CrmController::class, 'accounts']);\n $router->get('/contacts', [CrmController::class, 'contacts']);\n $router->get('/leads', [CrmController::class, 'leads']);\n $router->get('/tasks', [CrmController::class, 'activities']);\n $router->get('/layouts', [CrmController::class, 'layouts']);\n });\n\n // AI CRM notes.\n $router->group(['prefix' => 'ai-crm-notes'], static function (Router $router): void {\n $router->get('/activity/{activity}', [AiCrmNotesController::class, 'getByActivity']);\n $router->post('/activity/{activity}/log-to-crm', [AiCrmNotesController::class, 'logToCrmByActivity']);\n $router->post('/activity/{activity}/discard', [AiCrmNotesController::class, 'discardByActivity']);\n\n $router->get('/deal/{opportunity}', [AiCrmNotesController::class, 'getByOpportunity']);\n $router->post('/deal/{opportunity}/log-to-crm', [AiCrmNotesController::class, 'logToCrmByOpportunity']);\n $router->post('/deal/{opportunity}/discard', [AiCrmNotesController::class, 'discardByOpportunity']);\n });\n\n // Automated Reports\n $router->post('/automated-reports/interest', [UserAutomatedReportsController::class, 'trackInterest']);\n\n $router->group(\n [\n 'prefix' => 'automated-reports',\n 'middleware' => 'can:canAccessAiReports,' . User::class,\n ],\n static function (Router $router): void {\n $router->get('/', [UserAutomatedReportsController::class, 'list']);\n $router->delete('/{uuid}', [UserAutomatedReportsController::class, 'delete']);\n }\n );\n\n // Setup New Team / Trial\n $router->get('/features', [TeamSetupController::class, 'features']);\n $router->get('/tiers', [TeamSetupController::class, 'tiers']);\n $router->get('/calendars', [TeamSetupController::class, 'calendars']);\n $router->get('/crm-services', [TeamSetupController::class, 'crmServices']);\n $router->get('/connect-providers', [TeamSetupController::class, 'connectProviders']);\n $router->get('/integration-app-token', [TeamSetupController::class, 'integrationAppToken']);\n $router->post('/integration-app-connect', [TeamSetupController::class, 'integrationAppConnect']);\n\n // Notifications\n $router->get('/notifications/recent', [NotificationController::class, 'notifications']);\n $router->put('/notifications/read', [NotificationController::class, 'markAsRead']);\n $router->put('/notifications/read-multiple', [NotificationController::class, 'markMultipleAsRead']);\n $router->put('/notifications/read-all', [NotificationController::class, 'markAllAsRead']);\n\n // Live feed\n $router->get('/live-feed', [LiveFeedController::class, 'liveFeedItems']);\n\n // Languages\n $router->get('/languages', [LanguageController::class, 'list']);\n\n // The whole settings section will be moved out in a separate file\n $router->group(['prefix' => '/settings'], static function (Router $router): void {\n $router->group(['prefix' => '/organizations'], static function (Router $router): void {\n $router\n ->middleware(['can:kiosk,' . User::class])\n ->post('/', [OrganizationController::class, 'store'])\n ->name('kiosk.organizations.store');\n\n $router->group(['prefix' => '{team}', 'middleware' => ['teamMember']], static function (Router $router) {\n // Sync fields and team metadata\n $router->post('/fields/sync', [OrganizationSyncController::class, 'index'])\n ->name('api.sync.fields');\n\n // Conference Preferences.\n $router->post('/bot-avatar', [TeamPhotoController::class, 'updateBotAvatar'])\n ->name('update.bot.avatar');\n\n // Roles.\n $router->get('/roles', [OrganizationRolesController::class, 'index'])\n ->name('api.roles.index');\n\n $router->group(\n ['middleware' => 'permission:' . PermissionEnum::MANAGE_RETENTION_POLICY->value],\n static function (Router $router): void {\n $router->get('/retention-policy', [OrganizationRetentionPolicyController::class, 'index'])\n ->name('api.retention_policy.index');\n\n $router->post('/retention-policy', [OrganizationRetentionPolicyController::class, 'store'])\n ->name('api.retention_policy.update');\n }\n );\n\n $router->group(\n ['middleware' => 'permission:' . PermissionEnum::MANAGE_USERS->value],\n static function (Router $router): void {\n // Invitations.\n $router->get('/invitations', [InvitationController::class, 'index'])\n ->name('api.invitations.index');\n $router->post('/invitations/{invitation}', [InvitationController::class, 'resend'])\n ->name('api.invitations.resend');\n $router->delete('/invitations/{invitation}', [InvitationController::class, 'destroy'])\n ->name('api.invitations.delete');\n $router->post('/invitations', [InvitationController::class, 'store'])\n ->name('api.invitations.store');\n },\n );\n\n $router->group(\n ['middleware' => 'permission:' . PermissionEnum::MANAGE_TEAM->value],\n static function (Router $router): void {\n // Groups.\n $router->post('/groups', [GroupController::class, 'store']);\n $router->get('/groups/{group}', [GroupController::class, 'show']);\n $router->put('/groups/{group}', [GroupController::class, 'update']);\n\n $router->put('/group/{group}/scope', [GroupController::class, 'updateGroupScope']);\n\n $router->post('/group/{group}/dealRisks', [DealRiskController::class, 'updateSettings']);\n\n // Sidekick settings\n $router->group(\n ['middleware' => 'permission:' . PermissionEnum::MANAGE_SIDEKICK->value],\n static function (Router $router): void {\n $router->get('/sidekick', [SidekickController::class, 'getSidekickSettings']);\n $router\n ->post(\n '/group/{group}/sidekick',\n [SidekickController::class, 'setSidekickSettings'],\n )\n ->middleware(['can:updateSidekickSettings,group'])\n ->name('api.sidekick_settings.update');\n $router\n ->post('/sidekick', [SidekickController::class, 'setSidekickSettings'])\n ->middleware(['permission:' . PermissionEnum::UPDATE_ALL_SIDEKICK_SETTINGS->value])\n ->name('api.sidekick_settings.update_all');\n },\n );\n\n $router->get('/deal-insights', [TeamDealInsightsSettingController::class, 'index']);\n $router->patch('/deal-insights', [TeamDealInsightsSettingController::class, 'update']);\n\n // CRM Layout Management\n $router->group(['prefix' => 'layouts'], static function (Router $router): void {\n $router->get(\n '/{type}',\n [Controllers\\API\\LayoutManagementController::class, 'list'],\n )->name('layouts.list');\n\n $router->put(\n '/{layout}',\n [Controllers\\API\\LayoutManagementController::class, 'update'],\n )->name('layouts.update');\n });\n\n // Users.\n $router->put('/users/{user}', [TeamMemberController::class, 'update'])\n ->middleware(['permission:' . PermissionEnum::MANAGE_USERS->value])\n ->name('api.users.update');\n $router->delete('/users/{user}', [TeamMemberController::class, 'deactivate'])\n ->middleware(['permission:' . PermissionEnum::MANAGE_USERS->value])\n ->name('api.users.deactivate');\n\n $router->group(\n [\n 'prefix' => 'vocabulary',\n 'middleware' => 'can:manage,' . Vocabulary::class,\n ],\n static function (Router $router): void {\n $router\n ->get('/', [VocabularyController::class, 'list'])\n ->name('api.vocabulary.index');\n $router\n ->post('/', [VocabularyController::class, 'update'])\n ->name('api.vocabulary.create');\n\n $router->group(['prefix' => '{vocabulary}'], static function (Router $router): void {\n $router\n ->put('/', [VocabularyController::class, 'update'])\n ->middleware('can:update,vocabulary')\n ->name('api.vocabulary.update');\n $router\n ->delete('/', [VocabularyController::class, 'delete'])\n ->middleware('can:delete,vocabulary')\n ->name('api.vocabulary.delete');\n });\n },\n );\n\n $router->group(['prefix' => 'ai-context'], static function (Router $router): void {\n $router->get('/', [TeamAiContextController::class, 'index'])\n ->name('api.ai_context.get');\n $router->post('/', [TeamAiContextController::class, 'store'])\n ->name('api.ai_context.store');\n });\n\n $router->group(['prefix' => 'ai-automation'], static function (Router $router): void {\n $router->post('/fields/test-prompt', [TeamAiAutomationController::class, 'testCrmAiPrompt'])\n ->name('api.automation.templates.fields.test-prompt');\n // List CRM fields per object type\n $router->get('/fields/{objectType}', [TeamAiAutomationController::class, 'fields'])\n ->name('api.automation.fields');\n\n // List DealStages fields per object type\n $router->get('/stages', [TeamAiAutomationController::class, 'stages'])\n ->name('api.automation.stages');\n // Create CRM AI template\n $router->post('/templates', [TeamAiAutomationController::class, 'createTemplate'])\n ->name('api.automation.templates.create');\n\n // Export CRM updates\n $router->post('/templates/export-crm-updates', [TeamAiAutomationController::class, 'exportTemplateCrmUpdates'])\n ->name('api.automation.templates.export-crm-updates');\n\n // Update CRM AI template\n $router->put('/templates/{crmTemplate}', [TeamAiAutomationController::class, 'updateTemplate'])\n ->name('api.automation.templates.update');\n // Delete CRM AI template\n $router->delete('/templates/{crmTemplate}', [TeamAiAutomationController::class, 'deleteTemplate'])\n ->name('api.automation.templates.delete');\n // List all CRM AI templates\n $router->get('/templates', [TeamAiAutomationController::class, 'templates'])\n ->name('api.automation.templates.list');\n // Create CRM AI template field\n $router->post('/templates/{crmTemplate}/fields', [TeamAiAutomationController::class, 'createField'])\n ->name('api.automation.templates.fields.create');\n // Update CRM AI template field\n $router->put('/templates/{crmTemplate}/fields/{crmTemplateField}', [TeamAiAutomationController::class, 'updateField'])\n ->name('api.automation.templates.fields.update');\n // Delete CRM AI template field\n $router->delete('/templates/{crmTemplate}/fields/{crmTemplateField}', [TeamAiAutomationController::class, 'deleteField'])\n ->name('api.automation.templates.fields.delete');\n });\n\n $router->group(['prefix' => 'ai-call-scoring'], static function (Router $router): void {\n // Create AI scorecard\n $router->post('/ai-scorecards', [Controllers\\API\\AiCallScoring\\AiScorecardController::class, 'createAiScorecard'])\n ->name('api.ai-call-scoring.ai-scorecards.create');\n // Update AI scorecard\n $router->put('/ai-scorecards/{aiScorecard}', [Controllers\\API\\AiCallScoring\\AiScorecardController::class, 'updateAiScorecard'])\n ->name('api.ai-call-scoring.ai-scorecards.update');\n // Delete AI scorecard\n $router->delete('/ai-scorecards/{aiScorecard}', [Controllers\\API\\AiCallScoring\\AiScorecardController::class, 'deleteAiScorecard'])\n ->name('api.ai-call-scoring.ai-scorecards.delete');\n // Test AI scorecard prompt\n $router->post(\n '/ai-scorecards/{aiScorecard}/test-prompt',\n [\n Controllers\\API\\AiCallScoring\\AiScorecardController::class,\n 'testAiScorecardPrompt',\n ]\n )\n ->name('api.ai-call-scoring.ai-scorecards.test-prompt');\n\n // Create AI Scorecard rule\n $router->post('/ai-scorecards/{aiScorecard}/ai-scorecard-rules', [Controllers\\API\\AiCallScoring\\AiScorecardRuleController::class, 'createRule'])\n ->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.create');\n // Update AI Scorecard rule\n $router->put('/ai-scorecards/{aiScorecard}/ai-scorecard-rules/{aiScorecardRule}', [Controllers\\API\\AiCallScoring\\AiScorecardRuleController::class, 'updateAiScorecardRule'])\n ->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.update');\n // Delete AI Scorecard rule\n $router->delete('/ai-scorecards/{aiScorecard}/ai-scorecard-rules/{aiScorecardRule}', [Controllers\\API\\AiCallScoring\\AiScorecardRuleController::class, 'deleteAiScorecardRule'])\n ->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.delete');\n });\n\n // Theme, topics, triggers\n $router->get('/themes', [ThemeController::class, 'list']);\n $router\n ->post('/themes', [ThemeController::class, 'updateTheme'])\n ->middleware('can:manage,' . PlaybackTheme::class)\n ->name('api.theme.create');\n\n $router->group(\n [\n 'prefix' => 'theme/{theme}',\n 'middleware' => 'can:update,theme',\n ],\n static function (Router $router): void {\n $router\n ->put('/', [ThemeController::class, 'updateTheme'])\n ->name('api.theme.update');\n $router\n ->delete('/', [ThemeController::class, 'deleteTheme'])\n ->middleware('can:delete,theme')\n ->name('api.theme.delete');\n\n $router\n ->post('/topics', [TopicController::class, 'updateTopic'])\n ->middleware('can:createTopic,theme')\n ->name('api.topic.create');\n\n $router->group(\n [\n 'prefix' => 'topic/{topic}',\n 'middleware' => 'can:update,topic',\n ],\n static function (Router $router): void {\n $router\n ->put('/', [TopicController::class, 'updateTopic'])\n ->name('api.topic.update');\n $router\n ->delete('/', [TopicController::class, 'deleteTopic'])\n ->middleware('can:delete,topic')\n ->name('api.topic.delete');\n\n $router\n ->post('/triggers', [TopicTriggerController::class, 'updateTrigger'])\n ->middleware('can:createTrigger,topic')\n ->name('api.topic_trigger.create');\n\n $router->group(\n [\n 'prefix' => 'trigger/{topicTrigger}',\n 'middleware' => 'can:update,topicTrigger',\n ],\n static function (Router $router): void {\n $router\n ->put('/', [TopicTriggerController::class, 'updateTrigger'])\n ->name('api.topic_trigger.update');\n $router\n ->delete('/', [TopicTriggerController::class, 'deleteTrigger'])\n ->middleware('can:delete,topicTrigger')\n ->name('api.topic_trigger.delete');\n },\n );\n },\n );\n },\n );\n\n $router->post('/themes/import', [Controllers\\API\\Themes\\ImportTopicTriggerController::class, 'importThemes']);\n $router->get('/themes/export', [Controllers\\API\\Themes\\ExportTopicTriggerController::class, 'exportThemes']);\n\n // Auto-scoring\n $router->group(['prefix' => '/scorecards'], static function (Router $router) {\n $router->get('/', [Controllers\\API\\Scorecards\\ScorecardController::class, 'list']);\n $router->post('/', [Controllers\\API\\Scorecards\\ScorecardController::class, 'create']);\n $router->delete('/{scorecard}', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'delete',\n ]);\n $router->post('/validate-name', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'validateNameExists',\n ]);\n\n $router->get('/enabled-scorecard', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'getEnabledScorecard',\n ]);\n\n $router->get('/affected-scorecards', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'getAffectedScorecards',\n ]);\n\n $router->group(['prefix' => '/{scorecard}'], static function (Router $router) {\n $router->put('/', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'update',\n ]);\n $router->delete('/', [\n Controllers\\API\\Scorecards\\ScorecardController::class,\n 'delete',\n ]);\n\n $router->post('/rules', [\n Controllers\\API\\Scorecards\\ScorecardRuleController::class,\n 'create',\n ]);\n\n $router->post('/rules/{scorecardRule}', [\n Controllers\\API\\Scorecards\\ScorecardRuleController::class,\n 'update',\n ]);\n\n $router->delete('/rules/{scorecardRule}', [\n Controllers\\API\\Scorecards\\ScorecardRuleController::class,\n 'delete',\n ]);\n\n $router->post('/rules/{scorecardRule}/update-order', [\n Controllers\\API\\Scorecards\\ScorecardRuleController::class,\n 'updateOrder',\n ]);\n });\n });\n\n // Coaching Playbook.\n Route::get('/playbooks', [PlaybookController::class, 'all']);\n Route::get('/playbooksTree', [PlaybookController::class, 'tree']);\n Route::put('/playbooks/{playbook}', [PlaybookController::class, 'update']);\n Route::post('/playbooks', [PlaybookController::class, 'store']);\n Route::delete('/playbooks/{playbook}', [PlaybookController::class, 'destroy']);\n\n Route::prefix('/playbooks/{playbook}')->group(static function () {\n // Playbook Categories.\n Route::get('/categories', [PlaybookCategoryController::class, 'all']);\n Route::put('/categories/sequence', [PlaybookCategoryController::class, 'sequence']); // Respect order.\n Route::put('/categories/{category}', [PlaybookCategoryController::class, 'update']);\n Route::post('/categories', [PlaybookCategoryController::class, 'store']);\n Route::post('/test-prompt', [PlaybookController::class, 'testAiActivityTypePrompt']);\n Route::post('/prompt-suggestion', [PlaybookController::class, 'getPromptSuggestion']);\n Route::delete('/categories/{category}', [PlaybookCategoryController::class, 'destroy']);\n\n Route::prefix('/categories/{category}')->group(static function () {\n // Coaching Sections\n Route::get('/coaching-section', [Controllers\\Settings\\Coaching\\SectionsController::class, 'all']);\n Route::put('/coaching-section/sequence', [Controllers\\Settings\\Coaching\\SectionsController::class, 'sequence']);\n Route::put('/coaching-section/{coachingSection}', [Controllers\\Settings\\Coaching\\SectionsController::class, 'update']);\n Route::post('/coaching-section', [Controllers\\Settings\\Coaching\\SectionsController::class, 'store']);\n Route::delete('/coaching-section/{coachingSection}', [Controllers\\Settings\\Coaching\\SectionsController::class, 'destroy']);\n\n Route::prefix('coaching-section/{coachingSection}')->group(static function () {\n // Coaching Section Criteria\n Route::get('/coaching-section-criterion', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'all']);\n Route::put('/coaching-section-criterion/sequence', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'sequence']);\n Route::put('/coaching-section-criterion/{coachingSectionCriterion}', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'update']);\n Route::post('/coaching-section-criterion', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'store']);\n Route::delete('/coaching-section-criterion/{coachingSectionCriterion}', [Controllers\\Settings\\Coaching\\SectionCriteriaController::class, 'destroy']);\n });\n });\n });\n },\n );\n\n // List all AI scorecards (accessible to all team members, no MANAGE_TEAM required)\n $router->get('/ai-call-scoring/ai-scorecards', [Controllers\\API\\AiCallScoring\\AiScorecardController::class, 'aiScorecards'])\n ->name('api.ai-call-scoring.ai-scorecards.list');\n\n $router->middleware(['permission:' . PermissionEnum::MANAGE_ORGANIZATION_SETTINGS->value])\n ->group(static function (Router $router): void {\n // Job Titles.\n $router->get('/job-titles', [JobTitleController::class, 'all']);\n $router->put('/job-titles/{job}', [JobTitleController::class, 'update']);\n $router->post('/job-titles', [JobTitleController::class, 'store']);\n $router->delete('/job-titles/{job}', [JobTitleController::class, 'destroy']);\n\n // Team Settings.\n $router->put('/', [TeamSettingsController::class, 'update']);\n $router->put('/notifications', [TeamSettingsController::class, 'updateNotifications']);\n $router->put('/team-conference', [TeamConferenceSettingsController::class, 'update']);\n $router->put('/team-coaching', [TeamCoachingSettingsController::class, 'update']);\n $router->put('/team-softphone', [TeamSoftphoneSettingsController::class, 'update']);\n $router->put('/owner', [Controllers\\Settings\\Teams\\OrganizationSettingsController::class, 'updateOwner']);\n\n $router->put('/team-recording', [TeamRecordingSettingsController::class, 'update'])\n ->middleware(['permission:' . PermissionEnum::MANAGE_RECORDING->value]);\n\n // Key Moments.\n $router->get('/moments/{moment}', [Controllers\\Settings\\MomentController::class, 'show']);\n $router->put('/moments/{moment}', [Controllers\\Settings\\MomentController::class, 'update']);\n $router->post('/moments', [Controllers\\Settings\\MomentController::class, 'store']);\n $router->put('/activity', [TeamActivityController::class, 'store']);\n\n // Team Domains.\n $router->get('/domains', [Controllers\\Settings\\Teams\\TeamDomainsController::class, 'all']);\n $router->post('/domains', [Controllers\\Settings\\Teams\\TeamDomainsController::class, 'create']);\n $router->delete('/domains/{teamDomain}', [Controllers\\Settings\\Teams\\TeamDomainsController::class, 'destroy']);\n });\n });\n });\n });\n\n // Integrations\n $router->group(['middleware' => 'permission:' . PermissionEnum::MANAGE_INTEGRATIONS->value], static function (Router $router): void {\n $router->post('/integrations', [IntegrationController::class, 'internal'])\n ->name('api.integrations.internal');\n $router->put('/integrations', [IntegrationController::class, 'toggleStatus'])\n ->name('api.integrations.toggle_status');\n $router->delete('/integrations/{provider}', [IntegrationController::class, 'delete'])\n ->name('api.integrations.delete');\n });\n\n $router->get('/integrations', [IntegrationController::class, 'all'])\n ->middleware('permission:' . PermissionEnum::READ_INTEGRATIONS->value)\n ->name('api.integrations.index');\n\n // Slack API for getting slack channels list\n $router->get('{notificationProvider}/channels', [Controllers\\NotificationProviderController::class, 'channels']);\n\n\n // Team actions. XXX: These all need moving out to their own controllers.\n $router->group(['prefix' => 'organizations'], static function (Router $router): void {\n $router->get('current', [TeamController::class, 'current']);\n\n $router->group(['prefix' => '{team}', 'middleware' => ['teamMember']], static function (Router $router): void {\n $router->get('/', [TeamController::class, 'show']);\n\n $router->get('/categories', [TeamController::class, 'categories']);\n $router->get('/stages', [TeamController::class, 'stages']);\n $router->get('/users', [OrganizationMembersController::class, 'index'])\n ->name('organization.members.index');\n $router\n ->get('/users/download', [OrganizationMembersController::class, 'download'])\n ->middleware('permission:' . PermissionEnum::MANAGE_USERS->value)\n ->name('organization.members.download');\n $router->get('/licensed-roles', [OrganizationLicensesController::class, 'index'])\n ->middleware('permission:' . PermissionEnum::MANAGE_BILLING->value)\n ->name('organization.licensed-roles.index');\n $router->get('/invitations', [TeamController::class, 'invitations']);\n $router->get('/groups', [TeamController::class, 'groups']);\n $router->delete('/groups/{group}', [TeamController::class, 'deleteGroup'])\n ->middleware(['permission:' . PermissionEnum::DELETE_TEAM->value])\n ->name('api.groups.delete');\n $router->get('/job-titles', [TeamController::class, 'jobTitles']);\n $router->get('/slugs', [TeamController::class, 'slugs']);\n $router->put('/api-token', [TeamController::class, 'generateApiToken'])\n ->middleware(['permission:' . PermissionEnum::MANAGE_ORGANIZATION_SETTINGS->value]);\n $router->get('/key-moments', [MomentController::class, 'all']);\n });\n });\n\n // Internal Kiosk. This whole section will be moved out to a separate file\n $router\n ->prefix('kiosk')\n ->middleware('can:kiosk,' . User::class)\n ->group(static function (Router $router): void {\n // Partner actions.\n $router->get('/partners', [PartnersController::class, 'index']);\n\n // User actions.\n $router->post('/users/search', [SearchController::class, 'performBasicSearch']);\n\n // Team actions.\n $router->prefix('organizations')->group(static function (Router $router): void {\n $router->get('/', [OrganizationsController::class, 'show']);\n $router->put('/{team}', [OrganizationController::class, 'edit'])\n ->name('kiosk.organizations.edit');\n $router->get('/{team}/users', [OrganizationMembersController::class, 'index'])\n ->name('kiosk.organization.members.index');\n $router->get('onboardable', [OnboardController::class, 'available']);\n $router->delete('/{team}', [OrganizationsController::class, 'deactivateAccounts']);\n });\n\n // Automated reports\n // api/v1/kiosk/automated-reports\n $router->prefix('automated-reports')->group(static function (Router $router): void {\n $router->get('/form-data', [AutomatedReportsController::class, 'getCreateForm']);\n $router->get('/form-data/{reportUuid}', [AutomatedReportsController::class, 'getEditForm']);\n $router->post('/filters', [AutomatedReportsController::class, 'getFilters']);\n $router->post('/', [AutomatedReportsController::class, 'create']);\n $router->put('/{reportUuid}', [AutomatedReportsController::class, 'update']);\n $router->patch('/{reportUuid}', [AutomatedReportsController::class, 'partialUpdate']);\n $router->get('/', [AutomatedReportsController::class, 'list']);\n $router->get('/{reportUuid}', [AutomatedReportsController::class, 'get']);\n $router->delete('/{reportUuid}', [AutomatedReportsController::class, 'delete']);\n $router->post('/activities-count', [AutomatedReportsController::class, 'getActivitiesCount']);\n $router->get('/{reportUuid}/reports-count', [AutomatedReportsController::class, 'getReportsCount']);\n });\n\n // Activity actions.\n $router->post('/activity/search', [SearchController::class, 'performActivitySearch']);\n $router->prefix('activity/{activity}')->group(static function (Router $router): void {\n $router->post('check-playable', [SearchController::class, 'performActivityCheckPlayable']);\n $router->post('reset-crm-log', [SearchController::class, 'performResetCrmLogActivity']);\n $router->get('diarize-via-transcript', [KioskActivityController::class, 'diarizeViaTranscript']);\n $router->post('diarize-via-transcript', [KioskActivityController::class, 'diarizeViaTranscript']);\n $router->get('media-pipeline', [MediaPipelineController::class, 'getPipes']);\n $router->post('media-pipeline', [MediaPipelineController::class, 'updatePipe']);\n $router->post('language', [KioskActivityController::class, 'updateLanguage']);\n $router->post('trim', [KioskActivityController::class, 'trimActivity']);\n $router->get('troubleshoot', [KioskActivityController::class, 'troubleshootActivity']);\n $router->get('transcription', [KioskActivityController::class, 'getTranscriptions']);\n $router->post('speakers', [KioskActivityController::class, 'addSpeakers']);\n $router->post('crm-fields-fill', [KioskActivityController::class, 'crmFieldsFill']);\n $router->post('summary-highlights', [KioskActivityController::class, 'summaryHighlights']);\n });\n });\n});\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->group(['prefix' => 'events'], static function (Router $router): void {\n $router->post('authenticate', [Controllers\\PusherController::class, 'auth'])\n ->name(Routes::WEBHOOK_PUSHER_AUTH);\n });\n});\n\n$router->group(['middleware' => ['api']], static function (Router $router): void {\n $router->get('/extensions/auth', [ExtensionController::class, 'authenticate']);\n $router->get('/call-token/{team}/{participant?}', [ClientTokenController::class, 'generateToken']);\n});\n\n$router->group(['prefix' => 'user'], static function (Router $router): void {\n $router->get('chrome-extension-authentication', [ExtensionController::class, 'authenticate']);\n});\n\n$router->group(['middleware' => ['auth:api'], 'prefix' => 'sms'], static function (Router $router): void {\n $router->get('/{phoneNumber}', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'messages']);\n $router->get('/', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'messagesList']);\n $router->post('/', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'send']);\n $router->delete('/{activity}', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'redact']);\n $router->put('/{activity}', [Controllers\\Telephony\\TextMessaging\\MessageController::class, 'resend']);\n});\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/users/current', [UserController::class, 'current']);\n\n $router->get('/users/slug/{slug?}', [UserController::class, 'validateSlug']);\n\n // Profile Contact Information.\n $router->put(\n '/users/{user}/settings/profile',\n [Controllers\\Settings\\Profile\\ContactInformationController::class, 'update'],\n );\n\n $router->get('/users/{user}/email-sync-settings', [EmailSyncController::class, 'index']);\n $router->put('/users/{user}/email-sync-settings', [EmailSyncController::class, 'update']);\n\n // SMS Settings.\n $router->put('/users/{user}/settings/sms', [Controllers\\Settings\\Profile\\SmsController::class, 'update']);\n\n $router->get('/settings/timezones', [Controllers\\API\\Settings\\TimeZoneController::class, 'index'])\n ->name('settings.timezones.index');\n\n $router->put('/settings/user/deal-insights', [Controllers\\Settings\\Users\\UserSettingsController::class, 'update']);\n});\n\n$router->group(['prefix' => 'page', 'middleware' => ['api', 'auth:api']], static function () use ($router): void {\n $router->get('/playback/{activity}', [PlaybackController::class, 'show'])\n ->name('api.playback');\n $router->get('/on-demand', [OnDemandController::class, 'show'])\n ->name('api.activity.search');\n});\n\n$router->group(['prefix' => 'partners', 'middleware' => 'auth:partner-api'], static function () use ($router): void {\n $router->get('/', [PartnerController::class, 'me']);\n\n $router->group(['prefix' => 'organizations'], static function () use ($router): void {\n $router->get('/{team}', [PartnerController::class, 'fetchOrganization']);\n $router->post('/', [PartnerController::class, 'createOrganization']);\n });\n\n $router->group(['prefix' => 'groups'], static function () use ($router): void {\n $router->get('/{group}', [PartnerController::class, 'fetchGroup']);\n $router->post('/', [PartnerController::class, 'createGroup']);\n });\n\n $router->group(['prefix' => 'users'], static function () use ($router): void {\n $router->get('/{user}', [PartnerController::class, 'fetchUser']);\n $router->post('/', [PartnerController::class, 'createUser']);\n $router->delete('/{user}', [PartnerController::class, 'deactivateUser']);\n });\n\n $router->group(['prefix' => 'activities'], static function () use ($router): void {\n $router->get('/{activity}', [PartnerController::class, 'fetchActivity']);\n $router->get('/', [PartnerController::class, 'searchActivity']);\n });\n});\n\n$router->group(['prefix' => 'activity', 'middleware' => 'api'], static function () use ($router): void {\n // User only.\n $router->group(['middleware' => ['auth:api']], static function () use ($router): void {\n // Bulk delete\n $router->delete('/', [ActivityController::class, 'delete']);\n\n // Search.\n $router->get('/search', [ActivityController::class, 'search']);\n\n // All comments.\n $router->get('/comments', [ActivityController::class, 'fetchComments']);\n\n // Transcription AI\n $router->get('/{activity}/action-items', [Controllers\\API\\ActionItemsController::class, 'index']);\n $router->get('/{activity}/ai-call-scoring', [Controllers\\API\\AiCallScoring\\AiCallScoringController::class, 'index']);\n\n $router->get('/saved-search', [ActivityController::class, 'listActivitySearch'])->name('api.saved_search.index');\n $router->get('/saved-search/{search}', [ActivityController::class, 'fetchActivitySearch'])->name('api.saved_search.show');\n $router->post('/saved-search', [ActivityController::class, 'createActivitySearch'])->name('api.saved_search.create');\n $router->put('/saved-search/{search}', [ActivityController::class, 'updateActivitySearch'])->name('api.saved_search.update');\n $router->delete('/saved-search/{search}', [ActivityController::class, 'deleteActivitySearch'])->name('api.saved_search.delete');\n\n $router->post('/saved-search/{search}/nudges', [NudgeController::class, 'createAction'])->name('api.nudges.create');\n $router->put('/saved-search/{search}/nudges/{nudge}', [NudgeController::class, 'updateAction'])->name('api.nudges.update');\n $router->delete('/saved-search/{search}/nudges/{nudge}', [NudgeController::class, 'deleteAction'])->name('api.nudges.delete');\n\n // Live (coaching).\n $router->get('/live', [ActivityController::class, 'live']);\n $router->get('/{activity}/cloudfront-s3-media-keys', [ActivityController::class, 'fetchCloudFrontS3MediaKeys']);\n\n $router->post('/softphone', [SoftphoneController::class, 'create']);\n $router->put('/softphone', [SoftphoneController::class, 'createCoachParticipant']);\n $router->post('/softphone/dial', [SoftphoneController::class, 'dial']);\n $router->get('/softphone/{activity}', [SoftphoneController::class, 'fetch']);\n $router->delete('/softphone/{activity}', [SoftphoneController::class, 'endCall']);\n\n $router->post('softphone/{activity}/message', [SoftphoneController::class, 'message']);\n });\n\n // Activity actions.\n $router->group(['prefix' => '{activity}', 'middleware' => ['auth:api']], static function (Router $router): void {\n // User only.\n $router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n // Messages endpoint.\n $router->post('/message', [MessageController::class, 'message']);\n\n // Organizer actions.\n $router->put('/', [ActivityController::class, 'update']);\n $router->get('/', [ActivityController::class, 'show']);\n $router->delete('/', [ActivityController::class, 'destroy']);\n\n $router->post('/recording', [ActivityController::class, 'createRecording']);\n $router->put('/recording', [ActivityController::class, 'updateRecording']);\n $router->delete('/recording', [ActivityController::class, 'stopRecording']);\n\n $router->post('/summarize', [ActivityController::class, 'summarize']);\n\n // Sales Activity Playback action.\n $router->put('/favorite', [ActivityController::class, 'favorite']);\n $router->delete('/favorite', [ActivityController::class, 'unfavorite']);\n\n $router->put('/private', [ActivityController::class, 'markAsPrivate']);\n $router->delete('/private', [ActivityController::class, 'markAsPublic']);\n\n $router->put('/notification', [ActivityController::class, 'notify']);\n $router->delete('/notification/{notification}', [ActivityController::class, 'unnotify']);\n\n // Activity comments\n $router->put('/comment/{comment}', [ActivityController::class, 'updateComment']);\n $router->post('/comment/{comment}', [ActivityController::class, 'replyComment']);\n $router->post('/comment', [ActivityController::class, 'comment']);\n $router->delete('/comment/{comment}', [ActivityController::class, 'deleteComment']);\n $router->put('/comment/{comment}/visibility', [ActivityController::class, 'updateCommentVisibility']);\n\n $router->get('/coaching-sections', [ActivityController::class, 'coachingSections']);\n\n $router->put('/coach', [ActivityController::class, 'putCoachingFeedback']);\n $router->delete('/coach/{coachingFeedback}', [ActivityController::class, 'deleteCoachingFeedback']);\n\n $router->post('/coach-request', [ActivityController::class, 'coachRequest']);\n $router->post('/share', [ActivityController::class, 'share']);\n\n $router->post('/playlists', [ActivityController::class, 'addToPlaylist'])\n ->name('playlists.add.activity');\n\n $router->post('/key-moment', [MomentController::class, 'store']);\n\n $router->put('/play', [ActivityController::class, 'play']);\n\n $router->get('/stats', [ActivityController::class, 'stats']);\n\n $router->get('/topic-triggers', [ActivityController::class, 'fetchActivityTopicTriggers']);\n\n $router->post('/topic-triggers', [ActivityController::class, 'createActivityTopicTriggers']);\n\n $router->get('/auto-score', [Controllers\\API\\Scorecards\\AutoScoreController::class, 'getAutoScore']);\n $router->post('/auto-score', [Controllers\\API\\Scorecards\\AutoScoreController::class, 'updateAutoScore']);\n\n // Get Download link for an activity\n $router->get('/download', [Controllers\\PlaybackController::class, 'getDownloadUrl'])->name('getDownloadUrl');\n\n $router->post('/note', [ActivityController::class, 'note']);\n\n $router->post('/export', [ExportController::class, 'share'])\n ->middleware(['throttle:activity-export']);\n\n $router->post('/shareable-link', [ExportController::class, 'getShareableLink'])\n ->middleware(['throttle:activity-export-shareable-link']);\n\n $router->group(['prefix' => 'transcription'], static function (Router $router): void {\n $router->get('/', [TranscriptionController::class, 'getTranscriptionByActivity']);\n $router->get('/search', [TranscriptionController::class, 'searchAction']);\n $router->get('/download', [TranscriptionController::class, 'downloadTranscriptionByActivity'])\n ->middleware(['throttle:transcription-download']);\n $router->put('/attribution-flip/{participantA}/{participantB}', [Controllers\\API\\TranscriptionController::class, 'speakerAttributionFlip']);\n $router->put('/attribution-change/{participant}', [Controllers\\API\\TranscriptionController::class, 'speakerAttributionChange']);\n $router->get('/translation', [TranslationController::class, 'getTranslation']);\n });\n });\n });\n});\n\n$router->group(['middleware' => ['auth:api']], static function () use ($router) {\n $router->put('/subscription/{morphType}', [SubscriptionController::class, 'subscribe']);\n $router->delete('/subscription/{morphType}', [SubscriptionController::class, 'unsubscribe']);\n});\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/playlists', [PlaylistController::class, 'all'])->name('api.playlists.all');\n $router->get('/playlists/user', [PlaylistController::class, 'userPlaylists'])\n ->name('api.playlists.userPlaylists');\n $router->post('/playlists', [PlaylistController::class, 'store'])->name('api.playlists.store');\n\n $router->post('/playlists/{playlist}/share', [PlaylistController::class, 'share'])\n ->name('api.playlist.create.share');\n $router->get('/playlists/{playlist}/activities', [PlaylistController::class, 'activities'])\n ->name('api.playlist.activities');\n $router->delete('/playlists/{playlist}/shares/{playlistShare}', [PlaylistController::class, 'unshare'])\n ->name('api.playlist.unshare');\n $router->get('/playlists/{playlist}/shares', [PlaylistController::class, 'shares'])\n ->name('api.playlist.get.shares');\n $router->post('/playlists/{playlist}/lock', [PlaylistController::class, 'lock'])->name('api.playlist.lock');\n $router->post('/playlists/{playlist}/unlock', [PlaylistController::class, 'unlock'])\n ->name('api.playlist.unlock');\n $router->get(\n '/playlists/{playlist}/available-playlists',\n [PlaylistController::class, 'availablePlaylistsToMoveTo'],\n )->name('api.playlist.available');\n $router->put('/playlists/{playlist}', [PlaylistController::class, 'update'])->name('api.playlist.update');\n $router->delete('/playlists/{playlist}', [PlaylistController::class, 'destroy'])\n ->name('api.playlist.destroy');\n $router->put(\n '/playlists/{playlist}/tracks/{playlistActivity}',\n [PlaylistController::class, 'updatePlaylistTrack'],\n )->name('api.playlist.updatePlaylistTrack');\n $router->put(\n '/playlists/{playlist}/tracks/{playlistActivity}/move',\n [PlaylistController::class, 'moveToPlaylist'],\n )->name('api.playlist.moveToPlaylist');\n $router->delete(\n '/playlists/{playlist}/tracks/{playlistActivity}',\n [PlaylistController::class, 'removeFromPlaylist'],\n )->name('api.playlist.removeFromPlaylist');\n});\n\n$router->group(\n ['prefix' => '/opportunity/{opportunity}', 'middleware' => ['api']],\n static function (Router $router): void {\n // Opportunity comments\n $router->group(['prefix' => '/comment', 'middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/', [CommentsController::class, 'fetchComments']);\n $router->post('/', [CommentsController::class, 'comment']);\n\n $router->group(['prefix' => '{comment}'], static function (Router $router): void {\n $router->put('/', [CommentsController::class, 'updateComment']);\n $router->post('/', [CommentsController::class, 'replyComment']);\n $router->delete('/', [CommentsController::class, 'deleteComment']);\n $router->put('/visibility', [CommentsController::class, 'updateCommentVisibility']);\n });\n });\n },\n);\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->get('/playlist/{activity}.m3u8', [Controllers\\API\\PlaybackController::class, 'playlist']);\n $router->get('/media/{track}.m3u8', [Controllers\\API\\PlaybackController::class, 'media']);\n});\n\n$router->group(['middleware' => ['api']], static function (Router $router): void {\n // SSO email query.\n $router->get('/auth/sso/login', [Controllers\\API\\SsoController::class, 'ssoLogin'])->name('ssoLogin');\n});\n\n$router->get('/mobile-settings', [MobileSettingsController::class, 'getAll']);\n\n$router->put('/mobile-settings', [MobileSettingsController::class, 'updateSettings'])\n ->middleware(['auth:api', 'can:kiosk,' . User::class])\n ->name('api.kiosk.mobile_settings.update');\n\n// Ask Jiminny on deal level\n$router->get('deals/{opportunity}/ask-jiminny', [Controllers\\API\\DealLevelPromptsController::class, 'index'])\n ->middleware(['api', 'auth:api'])\n ->name('api.deals.ask-jiminny');\n\n$router->get('get-access-token/{provider?}', [SocialController::class, 'getAccessToken'])\n ->name('api.get_access_token')\n ->whereIn('provider', [SocialAccount::PROVIDER_HUBSPOT]);\n\n$router->group(['middleware' => ['auth:api']], static function (Router $router): void {\n $router->post('single-claim-token/{provider?}', [SocialController::class, 'getSingleUseClaim'])\n ->name('api.singe-claim-token');\n});\n\n$router->post('deauthorize-zoom-app', [SocialController::class, 'deauthorizeZoomApp'])\n ->name('api.deauthorize-zoom-app.recall-ai');\n\n$router->put('/conferences/{activity}/consent', [ConferencesOptInOutController::class, 'storeConsent'])\n ->middleware(['throttle:conference-consent'])\n ->name('api.conferences.store-consent');","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false}]...
|
-4568792548076702466
|
2696349033762639051
|
typing_pause
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Built-in Preview
Chrome
Firefox
Safari
Sync Changes
Hide This Notification
Code changed:
Hide
2
5
3
16
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
/**
* API routes.
*
* @see \Jiminny\Providers\RouteServiceProvider
*
* @var Router $router
*/
use Illuminate\Routing\Router;
use Illuminate\Support\Collection;
use Jiminny\Component\DealInsights\Forecast\Forecast;
use Jiminny\Component\Router\Routes;
use Jiminny\Contracts\Acl\PermissionEnum;
use Jiminny\Http\Controllers;
use Jiminny\Http\Controllers\API\ActivityController;
use Jiminny\Http\Controllers\API\AiCrmNotesController;
use Jiminny\Http\Controllers\API\ClientTokenController;
use Jiminny\Http\Controllers\API\CrmController;
use Jiminny\Http\Controllers\API\TeamInsights\TeamInsightsAiCallScoringController;
use Jiminny\Http\Controllers\ConferencesOptInOutController;
use Jiminny\Http\Controllers\API\DealRiskController;
use Jiminny\Http\Controllers\API\InstantMeetingController;
use Jiminny\Http\Controllers\API\LanguageController;
use Jiminny\Http\Controllers\API\LiveFeedController;
use Jiminny\Http\Controllers\API\MeetingsController;
use Jiminny\Http\Controllers\API\MessageController;
use Jiminny\Http\Controllers\API\MetadataController;
use Jiminny\Http\Controllers\API\MobileSettingsController;
use Jiminny\Http\Controllers\API\MomentController;
use Jiminny\Http\Controllers\API\NudgeController;
use Jiminny\Http\Controllers\API\NumberAllocatorController;
use Jiminny\Http\Controllers\API\Opportunity\CommentsController;
use Jiminny\Http\Controllers\API\OrganizationLicensesController;
use Jiminny\Http\Controllers\API\OrganizationMembersController;
use Jiminny\Http\Controllers\API\OrganizationRetentionPolicyController;
use Jiminny\Http\Controllers\API\OrganizationRolesController;
use Jiminny\Http\Controllers\API\OrganizationSyncController;
use Jiminny\Http\Controllers\API\Page\OnDemandController;
use Jiminny\Http\Controllers\API\Page\PlaybackController;
use Jiminny\Http\Controllers\API\PartnerController;
use Jiminny\Http\Controllers\API\PhoneNumberController;
use Jiminny\Http\Controllers\API\PlaylistController;
use Jiminny\Http\Controllers\API\Settings\EmailSyncController;
use Jiminny\Http\Controllers\API\SidekickController;
use Jiminny\Http\Controllers\API\SoftphoneController;
use Jiminny\Http\Controllers\API\SubscriptionController;
use Jiminny\Http\Controllers\API\TeamAiAutomationController;
use Jiminny\Http\Controllers\API\TeamAiContextController;
use Jiminny\Http\Controllers\API\TeamController;
use Jiminny\Http\Controllers\API\TeamInsights\ActivityStatsController;
use Jiminny\Http\Controllers\API\TeamInsights\CoachingFeedbacksController;
use Jiminny\Http\Controllers\API\TeamInsights\DashboardController;
use Jiminny\Http\Controllers\API\TeamInsights\EngagementController;
use Jiminny\Http\Controllers\API\TeamInsights\TeamInsightsAutomatedCallScoresController;
use Jiminny\Http\Controllers\API\TeamInsights\ThemeTopicsController;
use Jiminny\Http\Controllers\API\TeamInsights\TopicsInDealsController;
use Jiminny\Http\Controllers\API\TeamInsightsController;
use Jiminny\Http\Controllers\API\Themes\ThemeController;
use Jiminny\Http\Controllers\API\Themes\TopicController;
use Jiminny\Http\Controllers\API\Themes\TopicTriggerController;
use Jiminny\Http\Controllers\API\TranscriptionController;
use Jiminny\Http\Controllers\API\TranslationController;
use Jiminny\Http\Controllers\API\UserAutomatedReports\UserAutomatedReportsController;
use Jiminny\Http\Controllers\API\UserController;
use Jiminny\Http\Controllers\API\VocabularyController;
use Jiminny\Http\Controllers\Auth\ExtensionController;
use Jiminny\Http\Controllers\Auth\SocialController;
use Jiminny\Http\Controllers\ExportController;
use Jiminny\Http\Controllers\Kiosk\ActivityController as KioskActivityController;
use Jiminny\Http\Controllers\Kiosk\AutomatedReportsController;
use Jiminny\Http\Controllers\Kiosk\MediaPipelineController;
use Jiminny\Http\Controllers\Kiosk\OrganizationsController;
use Jiminny\Http\Controllers\Kiosk\PartnersController;
use Jiminny\Http\Controllers\Kiosk\SearchController;
use Jiminny\Http\Controllers\Kiosk\Teams\OnboardController;
use Jiminny\Http\Controllers\NotificationController;
use Jiminny\Http\Controllers\Settings\GroupController;
use Jiminny\Http\Controllers\Settings\JobTitleController;
use Jiminny\Http\Controllers\Settings\PlaybookCategoryController;
use Jiminny\Http\Controllers\Settings\PlaybookController;
use Jiminny\Http\Controllers\Settings\Teams\IntegrationController;
use Jiminny\Http\Controllers\Settings\Teams\InvitationController;
use Jiminny\Http\Controllers\Settings\Teams\TeamActivityController;
use Jiminny\Http\Controllers\Settings\Teams\TeamCoachingSettingsController;
use Jiminny\Http\Controllers\Settings\Teams\TeamConferenceSettingsController;
use Jiminny\Http\Controllers\Settings\Teams\TeamController as OrganizationController;
use Jiminny\Http\Controllers\Settings\Teams\TeamDealInsightsSettingController;
use Jiminny\Http\Controllers\Settings\Teams\TeamMemberController;
use Jiminny\Http\Controllers\Settings\Teams\TeamPhotoController;
use Jiminny\Http\Controllers\Settings\Teams\TeamRecordingSettingsController;
use Jiminny\Http\Controllers\Settings\Teams\TeamSettingsController;
use Jiminny\Http\Controllers\Settings\Teams\TeamSoftphoneSettingsController;
use Jiminny\Http\Controllers\TeamSetupController;
use Jiminny\Models;
use Jiminny\Models\PlaybackTheme;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\User;
use Jiminny\Models\Vocabulary;
use Jiminny\Repositories;
use Jiminny\Mcp\Servers\JiminnyServer;
use Laravel\Mcp\Facades\Mcp;
// mcp.audit MUST stay outermost so its $next($request) call wraps the auth
// and tier guards. Otherwise 401 (auth:api) and 403 (mcp.tier) rejections
// short-circuit before McpAuditMiddleware::handle ever runs and we lose
// audit rows for exactly the requests the security log most needs to capture.
// McpAuditMiddleware::writeAuditRow null-checks $request->user(), so writing
// pre-auth is safe.
Mcp::web('/mcp', JiminnyServer::class)
->middleware(['mcp.audit', 'auth:api', 'mcp.tier']);
$router->group(['middleware' => ['auth:api']], static function (Router $router): void {
$router->get('/metadata/extension-app', [MetadataController::class, 'extension']);
$router->get('/', [NumberAllocatorController::class, 'generate']);
$router->delete('/key-moment/{activityMoment}', [MomentController::class, 'destroy']);
$router->post('/instant-meeting/start', [InstantMeetingController::class, 'postRequestBotAtUrl'])
->middleware(['permission:' . PermissionEnum::RECORD_MEETING->value])
->name('instant-meeting.start');
// Meeting creation endpoint for Outlook add-in
$router->post('/meetings', [MeetingsController::class, 'create'])
->middleware(['permission:' . PermissionEnum::RECORD_MEETING->value])
->name('meetings.create');
// Number provisioning and search.
$router->get('/phone-numbers', [NumberAllocatorController::class, 'generate']);
$router->get('/phone-numbers/{number}', [PhoneNumberController::class, 'number']);
$router->group(['prefix' => 'deal-insights'], static function (Router $router): void {
$router->get('/forecast', [
Controllers\API\DealInsights\DealsController::class,
'getForecast',
])->defaults('period', Forecast::PERIOD_QUARTER);
$router->get('/deals/{stage?}', [
Controllers\API\DealInsights\DealsController::class,
'list',
])->defaults('stage', \Jiminny\Component\DealInsights\CriteriaInterface::STAGE_ALL);
$router->get('/details/details-daily/{opportunityId}/{date}', [
Controllers\API\DealInsights\DealsController::class,
'detailsDaily',
]);
$router->put('/deals/{opportunity}/edit-fields', [
Controllers\API\DealInsights\DealsController::class,
'updateFields',
]);
$router->get('/externalId/{dealId}', [
Controllers\API\DealInsights\DealsController::class,
'externalDealId',
]);
$router->put('/dealRisk/{dealRisk}', [DealRiskController::class, 'toggleActivity']);
});
$router->get('/team-insights/users', [TeamInsightsController::class, 'fetchUsers'])
->name('team_insights.users');
$router->get('/team-insights/dashboard', [DashboardController::class, 'fetch'])
->name('team_insights.dashboard');
// Team Insights - Coaching Feedbacks
$router->get('/team-insights/coaching-feedbacks-over-time', [CoachingFeedbacksController::class, 'fetch'])
->name('team_insights.coaching_feedbacks_over_time');
$router
->get('/team-insights/coaching-feedbacks-over-time/download', [CoachingFeedbacksController::class, 'download'])
->name('team_insights.coaching_feedbacks_over_time.download');
$router->get(
'/team-insights/coaching-feedbacks-over-time/drill-down',
[CoachingFeedbacksController::class, 'drillDown'],
)->name('team_insights.coaching_feedbacks_over_time.drill_down');
// Team Insights - Automated Call Scores
$router->get(
'/team-insights/automated-call-scores-over-time',
[TeamInsightsAutomatedCallScoresController::class, 'index'],
)->name('team_insights.automated_call_scores_over_time.index');
$router->get(
'/team-insights/automated-call-scores-over-time/drill-down',
[TeamInsightsAutomatedCallScoresController::class, 'show'],
)->name('team_insights.automated_call_scores_over_time.show');
// Team Insights - AI Call Scoring
$router->get(
'/team-insights/ai-call-scoring-over-time',
[TeamInsightsAiCallScoringController::class, 'index'],
)->name('team_insights.ai_call_scoring_over_time.index');
$router->get(
'/team-insights/ai-call-scoring-over-time/drill-down',
[TeamInsightsAiCallScoringController::class, 'show'],
)->name('team_insights.ai_call_scoring_over_time.show');
$router->get('/team-insights/engagement', [ActivityStatsController::class, 'fetch'])
->name('team_insights.engagement');
$router->get('/team-insights/engagement/drill-down/{engagementType}', [ActivityStatsController::class, 'drillDown'])
->name('team_insights.engagement.drill_down');
$router->get('/team-insights/topics', [ThemeTopicsController::class, 'getTopics'])
->name('team_insights.topics.index');
$router->get('/team-insights/topics/{topic}', [ThemeTopicsController::class, 'fetch'])
->name('team_insights.topics.show');
$router->get('/team-insights/topics/{topic}/drill-down', [ThemeTopicsController::class, 'drillDown'])
->name('team_insights.topics.drill_down');
$router->group(['prefix' => 'team-insights'], static function (Router $router): void {
$router->group(['prefix' => 'conversations'], static function (Router $router): void {
$router->get('/', [
Controllers\API\TeamInsights\ConversationsController::class,
'fetch',
]);
$router->group(['prefix' => 'drill-down'], static function (Router $router): void {
$router
->get('/{activityChannel}/{drillDownType}', [
Controllers\API\TeamInsights\ConversationsController::class,
'drillDown',
])
->where(
'activityChannel',
Collection::make(Models\Activity::CHANNELS)->join('|'),
)
->where(
'drillDownType',
Collection::make(Repositories\TeamInsightsRepository::CONVERSATION_DRILLDOWNS)
->join('|'),
);
});
});
$router->group(['prefix' => 'coaching'], static function (Router $router): void {
$router->get('/', [EngagementController::class, 'fetch']);
$router->group(['prefix' => 'drill-down'], static function (Router $router): void {
$router
->get('/{coachingType}/{drillDownType?}', [EngagementController::class, 'drillDown'])
->where(
'coachingType',
Collection::make(EngagementController::COACHING_TYPES)->join('|'),
)
->where(
'drillDownType',
Collection::make(EngagementController::COACHING_DRILLDOWNS)->join('|'),
);
});
});
});
$router->get('/topics-in-deals', [TopicsInDealsController::class, 'topics'])
->name('topics_in_deals.topics');
$router->get('/topics-in-deals/topic-triggers', [TopicsInDealsController::class, 'topicTriggers'])
->name('topics_in_deals.topic_triggers');
$router->get('/compare-topics-in-deals', [TopicsInDealsController::class, 'comparison'])
->name('topics_in_deals.comparison');
// CRM actions.
$router->group(['prefix' => 'crm'], static function (Router $router): void {
$router->get('/search', [CrmController::class, 'search']);
$router->get('/opportunity', [CrmController::class, 'opportunities']);
$router->get('/customers', [CrmController::class, 'customers']);
$router->get('/accounts', [CrmController::class, 'accounts']);
$router->get('/contacts', [CrmController::class, 'contacts']);
$router->get('/leads', [CrmController::class, 'leads']);
$router->get('/tasks', [CrmController::class, 'activities']);
$router->get('/layouts', [CrmController::class, 'layouts']);
});
// AI CRM notes.
$router->group(['prefix' => 'ai-crm-notes'], static function (Router $router): void {
$router->get('/activity/{activity}', [AiCrmNotesController::class, 'getByActivity']);
$router->post('/activity/{activity}/log-to-crm', [AiCrmNotesController::class, 'logToCrmByActivity']);
$router->post('/activity/{activity}/discard', [AiCrmNotesController::class, 'discardByActivity']);
$router->get('/deal/{opportunity}', [AiCrmNotesController::class, 'getByOpportunity']);
$router->post('/deal/{opportunity}/log-to-crm', [AiCrmNotesController::class, 'logToCrmByOpportunity']);
$router->post('/deal/{opportunity}/discard', [AiCrmNotesController::class, 'discardByOpportunity']);
});
// Automated Reports
$router->post('/automated-reports/interest', [UserAutomatedReportsController::class, 'trackInterest']);
$router->group(
[
'prefix' => 'automated-reports',
'middleware' => 'can:canAccessAiReports,' . User::class,
],
static function (Router $router): void {
$router->get('/', [UserAutomatedReportsController::class, 'list']);
$router->delete('/{uuid}', [UserAutomatedReportsController::class, 'delete']);
}
);
// Setup New Team / Trial
$router->get('/features', [TeamSetupController::class, 'features']);
$router->get('/tiers', [TeamSetupController::class, 'tiers']);
$router->get('/calendars', [TeamSetupController::class, 'calendars']);
$router->get('/crm-services', [TeamSetupController::class, 'crmServices']);
$router->get('/connect-providers', [TeamSetupController::class, 'connectProviders']);
$router->get('/integration-app-token', [TeamSetupController::class, 'integrationAppToken']);
$router->post('/integration-app-connect', [TeamSetupController::class, 'integrationAppConnect']);
// Notifications
$router->get('/notifications/recent', [NotificationController::class, 'notifications']);
$router->put('/notifications/read', [NotificationController::class, 'markAsRead']);
$router->put('/notifications/read-multiple', [NotificationController::class, 'markMultipleAsRead']);
$router->put('/notifications/read-all', [NotificationController::class, 'markAllAsRead']);
// Live feed
$router->get('/live-feed', [LiveFeedController::class, 'liveFeedItems']);
// Languages
$router->get('/languages', [LanguageController::class, 'list']);
// The whole settings section will be moved out in a separate file
$router->group(['prefix' => '/settings'], static function (Router $router): void {
$router->group(['prefix' => '/organizations'], static function (Router $router): void {
$router
->middleware(['can:kiosk,' . User::class])
->post('/', [OrganizationController::class, 'store'])
->name('kiosk.organizations.store');
$router->group(['prefix' => '{team}', 'middleware' => ['teamMember']], static function (Router $router) {
// Sync fields and team metadata
$router->post('/fields/sync', [OrganizationSyncController::class, 'index'])
->name('api.sync.fields');
// Conference Preferences.
$router->post('/bot-avatar', [TeamPhotoController::class, 'updateBotAvatar'])
->name('update.bot.avatar');
// Roles.
$router->get('/roles', [OrganizationRolesController::class, 'index'])
->name('api.roles.index');
$router->group(
['middleware' => 'permission:' . PermissionEnum::MANAGE_RETENTION_POLICY->value],
static function (Router $router): void {
$router->get('/retention-policy', [OrganizationRetentionPolicyController::class, 'index'])
->name('api.retention_policy.index');
$router->post('/retention-policy', [OrganizationRetentionPolicyController::class, 'store'])
->name('api.retention_policy.update');
}
);
$router->group(
['middleware' => 'permission:' . PermissionEnum::MANAGE_USERS->value],
static function (Router $router): void {
// Invitations.
$router->get('/invitations', [InvitationController::class, 'index'])
->name('api.invitations.index');
$router->post('/invitations/{invitation}', [InvitationController::class, 'resend'])
->name('api.invitations.resend');
$router->delete('/invitations/{invitation}', [InvitationController::class, 'destroy'])
->name('api.invitations.delete');
$router->post('/invitations', [InvitationController::class, 'store'])
->name('api.invitations.store');
},
);
$router->group(
['middleware' => 'permission:' . PermissionEnum::MANAGE_TEAM->value],
static function (Router $router): void {
// Groups.
$router->post('/groups', [GroupController::class, 'store']);
$router->get('/groups/{group}', [GroupController::class, 'show']);
$router->put('/groups/{group}', [GroupController::class, 'update']);
$router->put('/group/{group}/scope', [GroupController::class, 'updateGroupScope']);
$router->post('/group/{group}/dealRisks', [DealRiskController::class, 'updateSettings']);
// Sidekick settings
$router->group(
['middleware' => 'permission:' . PermissionEnum::MANAGE_SIDEKICK->value],
static function (Router $router): void {
$router->get('/sidekick', [SidekickController::class, 'getSidekickSettings']);
$router
->post(
'/group/{group}/sidekick',
[SidekickController::class, 'setSidekickSettings'],
)
->middleware(['can:updateSidekickSettings,group'])
->name('api.sidekick_settings.update');
$router
->post('/sidekick', [SidekickController::class, 'setSidekickSettings'])
->middleware(['permission:' . PermissionEnum::UPDATE_ALL_SIDEKICK_SETTINGS->value])
->name('api.sidekick_settings.update_all');
},
);
$router->get('/deal-insights', [TeamDealInsightsSettingController::class, 'index']);
$router->patch('/deal-insights', [TeamDealInsightsSettingController::class, 'update']);
// CRM Layout Management
$router->group(['prefix' => 'layouts'], static function (Router $router): void {
$router->get(
'/{type}',
[Controllers\API\LayoutManagementController::class, 'list'],
)->name('layouts.list');
$router->put(
'/{layout}',
[Controllers\API\LayoutManagementController::class, 'update'],
)->name('layouts.update');
});
// Users.
$router->put('/users/{user}', [TeamMemberController::class, 'update'])
->middleware(['permission:' . PermissionEnum::MANAGE_USERS->value])
->name('api.users.update');
$router->delete('/users/{user}', [TeamMemberController::class, 'deactivate'])
->middleware(['permission:' . PermissionEnum::MANAGE_USERS->value])
->name('api.users.deactivate');
$router->group(
[
'prefix' => 'vocabulary',
'middleware' => 'can:manage,' . Vocabulary::class,
],
static function (Router $router): void {
$router
->get('/', [VocabularyController::class, 'list'])
->name('api.vocabulary.index');
$router
->post('/', [VocabularyController::class, 'update'])
->name('api.vocabulary.create');
$router->group(['prefix' => '{vocabulary}'], static function (Router $router): void {
$router
->put('/', [VocabularyController::class, 'update'])
->middleware('can:update,vocabulary')
->name('api.vocabulary.update');
$router
->delete('/', [VocabularyController::class, 'delete'])
->middleware('can:delete,vocabulary')
->name('api.vocabulary.delete');
});
},
);
$router->group(['prefix' => 'ai-context'], static function (Router $router): void {
$router->get('/', [TeamAiContextController::class, 'index'])
->name('api.ai_context.get');
$router->post('/', [TeamAiContextController::class, 'store'])
->name('api.ai_context.store');
});
$router->group(['prefix' => 'ai-automation'], static function (Router $router): void {
$router->post('/fields/test-prompt', [TeamAiAutomationController::class, 'testCrmAiPrompt'])
->name('api.automation.templates.fields.test-prompt');
// List CRM fields per object type
$router->get('/fields/{objectType}', [TeamAiAutomationController::class, 'fields'])
->name('api.automation.fields');
// List DealStages fields per object type
$router->get('/stages', [TeamAiAutomationController::class, 'stages'])
->name('api.automation.stages');
// Create CRM AI template
$router->post('/templates', [TeamAiAutomationController::class, 'createTemplate'])
->name('api.automation.templates.create');
// Export CRM updates
$router->post('/templates/export-crm-updates', [TeamAiAutomationController::class, 'exportTemplateCrmUpdates'])
->name('api.automation.templates.export-crm-updates');
// Update CRM AI template
$router->put('/templates/{crmTemplate}', [TeamAiAutomationController::class, 'updateTemplate'])
->name('api.automation.templates.update');
// Delete CRM AI template
$router->delete('/templates/{crmTemplate}', [TeamAiAutomationController::class, 'deleteTemplate'])
->name('api.automation.templates.delete');
// List all CRM AI templates
$router->get('/templates', [TeamAiAutomationController::class, 'templates'])
->name('api.automation.templates.list');
// Create CRM AI template field
$router->post('/templates/{crmTemplate}/fields', [TeamAiAutomationController::class, 'createField'])
->name('api.automation.templates.fields.create');
// Update CRM AI template field
$router->put('/templates/{crmTemplate}/fields/{crmTemplateField}', [TeamAiAutomationController::class, 'updateField'])
->name('api.automation.templates.fields.update');
// Delete CRM AI template field
$router->delete('/templates/{crmTemplate}/fields/{crmTemplateField}', [TeamAiAutomationController::class, 'deleteField'])
->name('api.automation.templates.fields.delete');
});
$router->group(['prefix' => 'ai-call-scoring'], static function (Router $router): void {
// Create AI scorecard
$router->post('/ai-scorecards', [Controllers\API\AiCallScoring\AiScorecardController::class, 'createAiScorecard'])
->name('api.ai-call-scoring.ai-scorecards.create');
// Update AI scorecard
$router->put('/ai-scorecards/{aiScorecard}', [Controllers\API\AiCallScoring\AiScorecardController::class, 'updateAiScorecard'])
->name('api.ai-call-scoring.ai-scorecards.update');
// Delete AI scorecard
$router->delete('/ai-scorecards/{aiScorecard}', [Controllers\API\AiCallScoring\AiScorecardController::class, 'deleteAiScorecard'])
->name('api.ai-call-scoring.ai-scorecards.delete');
// Test AI scorecard prompt
$router->post(
'/ai-scorecards/{aiScorecard}/test-prompt',
[
Controllers\API\AiCallScoring\AiScorecardController::class,
'testAiScorecardPrompt',
]
)
->name('api.ai-call-scoring.ai-scorecards.test-prompt');
// Create AI Scorecard rule
$router->post('/ai-scorecards/{aiScorecard}/ai-scorecard-rules', [Controllers\API\AiCallScoring\AiScorecardRuleController::class, 'createRule'])
->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.create');
// Update AI Scorecard rule
$router->put('/ai-scorecards/{aiScorecard}/ai-scorecard-rules/{aiScorecardRule}', [Controllers\API\AiCallScoring\AiScorecardRuleController::class, 'updateAiScorecardRule'])
->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.update');
// Delete AI Scorecard rule
$router->delete('/ai-scorecards/{aiScorecard}/ai-scorecard-rules/{aiScorecardRule}', [Controllers\API\AiCallScoring\AiScorecardRuleController::class, 'deleteAiScorecardRule'])
->name('api.ai-call-scoring.ai-scorecards.ai-scorecard-rules.delete');
});
// Theme, topics, triggers
$router->get('/themes', [ThemeController::class, 'list']);
$router
->post('/themes', [ThemeController::class, 'updateTheme'])
->middleware('can:manage,' . PlaybackTheme::class)
->name('api.theme.create');
$router->group(
[
'prefix' => 'theme/{theme}',
'middleware' => 'can:update,theme',
],
static function (Router $router): void {
$router
->put('/', [ThemeController::class, 'updateTheme'])
->name('api.theme.update');
$router
->delete('/', [ThemeController::class, 'deleteTheme'])
->middleware('can:delete,theme')
->name('api.theme.delete');
$router
->post('/topics', [TopicController::class, 'updateTopic'])
->middleware('can:createTopic,theme')
->name('api.topic.create');
$router->group(
[
'prefix' => 'topic/{topic}',
'middleware' => 'can:update,topic',
],
static function (Router $router): void {
$router
->put('/', [TopicController::class, 'updateTopic'])
->name('api.topic.update');
$router
->delete('/', [TopicController::class, 'deleteTopic'])
->middleware('can:delete,topic')
->name('api.topic.delete');
$router
->post('/triggers', [TopicTriggerController::class, 'updateTrigger'])
->middleware('can:createTrigger,topic')
->name('api.topic_trigger.create');
$router->group(
[
'prefix' => 'trigger/{topicTrigger}',
'middleware' => 'can:update,topicTrigger',
],
static function (Router $router): void {
$router
->put('/', [TopicTriggerController::class, 'updateTrigger'])
->name('api.topic_trigger.update');
$router
->delete('/', [TopicTriggerController::class, 'deleteTrigger'])
->middleware('can:delete,topicTrigger')
->name('api.topic_trigger.delete');
},
);
},
);
},
);
$router->post('/themes/import', [Controllers\API\Themes\ImportTopicTriggerController::class, 'importThemes']);
$router->get('/themes/export', [Controllers\API\Themes\ExportTopicTriggerController::class, 'exportThemes']);
// Auto-scoring
$router->group(['prefix' => '/scorecards'], static function (Router $router) {
$router->get('/', [Controllers\API\Scorecards\ScorecardController::class, 'list']);
$router->post('/', [Controllers\API\Scorecards\ScorecardController::class, 'create']);
$router->delete('/{scorecard}', [
Controllers\API\Scorecards\ScorecardController::class,
'delete',
]);
$router->post('/validate-name', [
Controllers\API\Scorecards\ScorecardController::class,
'validateNameExists',
]);
$router->get('/enabled-scorecard', [
Controllers\API\Scorecards\ScorecardController::class,
'getEnabledScorecard',
]);
$router->get('/affected-scorecards', [
Controllers\API\Scorecards\ScorecardController::class,
'getAffectedScorecards',
]);
$router->group(['prefix' => '/{scorecard}'], static function (Router $router) {
$router->put('/', [
Controllers\API\Scorecards\ScorecardController::class,
'update',
]);
$router->delete('/', [
Controllers\API\Scorecards\ScorecardController::class,
'delete',
]);
$router->post('/rules', [
Controllers\API\Scorecards\ScorecardRuleController::class,
'create',
]);
$router->post('/rules/{scorecardRule}', [
Controllers\API\Scorecards\ScorecardRuleController::class,
'update',
]);
$router->delete('/rules/{scorecardRule}', [
Controllers\API\Scorecards\ScorecardRuleController::class,
'delete',
]);
$router->post('/rules/{scorecardRule}/update-order', [
Controllers\API\Scorecards\ScorecardRuleController::class,
'updateOrder',
]);
});
});
// Coaching Playbook.
Route::get('/playbooks', [PlaybookController::class, 'all']);
Route::get('/playbooksTree', [PlaybookController::class, 'tree']);
Route::put('/playbooks/{playbook}', [PlaybookController::class, 'update']);
Route::post('/playbooks', [PlaybookController::class, 'store']);
Route::delete('/playbooks/{playbook}', [PlaybookController::class, 'destroy']);
Route::prefix('/playbooks/{playbook}')->group(static function () {
// Playbook Categories.
Route::get('/categories', [PlaybookCategoryController::class, 'all']);
Route::put('/categories/sequence', [PlaybookCategoryController::class, 'sequence']); // Respect order.
Route::put('/categories/{category}', [PlaybookCategoryController::class, 'update']);
Route::post('/categories', [PlaybookCategoryController::class, 'store']);
Route::post('/test-prompt', [PlaybookController::class, 'testAiActivityTypePrompt']);
Route::post('/prompt-suggestion', [PlaybookController::class, 'getPromptSuggestion']);
Route::delete('/categories/{category}', [PlaybookCategoryController::class, 'destroy']);
Route::prefix('/categories/{category}')->group(static function () {
// Coaching Sections
Route::get('/coaching-section', [Controllers\Settings\Coaching\SectionsController::class, 'all']);
Route::put('/coaching-section/sequence', [Controllers\Settings\Coaching\SectionsController::class, 'sequence']);
Route::put('/coaching-section/{coachingSection}', [Controllers\Settings\Coaching\SectionsController::class, 'update']);
Route::post('/coaching-section', [Controllers\Settings\Coaching\SectionsController::class, 'store']);
Route::delete('/coaching-section/{coachingSection}', [Controllers\Settings\Coaching\SectionsController::class, 'destroy']);
Route::prefix('coaching-section/{coachingSection}')->group(static function () {
// Coaching Section Criteria
Route::get('/coaching-section-criterion', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'all']);
Route::put('/coaching-section-criterion/sequence', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'sequence']);
Route::put('/coaching-section-criterion/{coachingSectionCriterion}', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'update']);
Route::post('/coaching-section-criterion', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'store']);
Route::delete('/coaching-section-criterion/{coachingSectionCriterion}', [Controllers\Settings\Coaching\SectionCriteriaController::class, 'destroy']);
});
});
});
},
);
// List all AI scorecards (accessible to all team members, no MANAGE_TEAM required)
$router->get('/ai-call-scoring/ai-scorecards', [Controllers\API\AiCallScoring\AiScorecardController::class, 'aiScorecards'])
->name('api.ai-call-scoring.ai-scorecards.list');
$router->middleware(['permission:' . PermissionEnum::MANAGE_ORGANIZATION_SETTINGS->value])
->group(static function (Router $router): void {
// Job Titles.
$router->get('/job-titles', [JobTitleController::class, 'all']);
$router->put('/job-titles/{job}', [JobTitleController::class, 'update']);
$router->post('/job-titles', [JobTitleController::class, 'store']);
$router->delete('/job-titles/{job}', [JobTitleController::class, 'destroy']);
// Team Settings.
$router->put('/', [TeamSettingsController::class, 'update']);
$router->put('/notifications', [TeamSettingsController::class, 'updateNotifications']);
$router->put('/team-conference', [TeamConferenceSettingsController::class, 'update']);
$router->put('/team-coaching', [TeamCoachingSettingsController::class, 'update']);
$router->put('/team-softphone', [TeamSoftphoneSettingsController::class, 'update']);
$router->put('/owner', [Controllers\Settings\Teams\OrganizationSettingsController::class, 'updateOwner']);
$router->put('/team-recording', [TeamRecordingSettingsController::class, 'update'])
->middleware(['permission:' . PermissionEnum::MANAGE_RECORDING->value]);
// Key Moments.
$router->get('/moments/{moment}', [Controllers\Settings\MomentController::class, 'show']);
$router->put('/moments/{moment}', [Controllers\Settings\MomentController::class, 'update']);
$router->post('/moments', [Controllers\Settings\MomentController::class, 'store']);
$router->put('/activity', [TeamActivityController::class, 'store']);
// Team Domains.
$router->get('/domains', [Controllers\Settings\Teams\TeamDomainsController::class, 'all']);
$router->post('/domains', [Controllers\Settings\Teams\TeamDomainsController::class, 'create']);
$router->delete('/domains/{teamDomain}', [Controllers\Settings\Teams\TeamDomainsController::class, 'destroy']);
});
});
});
});
// Integrations
$router->group(['middleware' => 'permission:' . PermissionEnum::MANAGE_INTEGRATIONS->value], static function (Router $router): void {
$router->post('/integrations', [IntegrationController::class, 'internal'])
->name('api.integrations.internal');
$router->put('/integrations', [IntegrationController::class, 'toggleStatus'])
->name('api.integrations.toggle_status');
$router->delete('/integrations/{provider}', [IntegrationController::class, 'delete'])
->name('api.integrations.delete');
});
$router->get('/integrations', [IntegrationController::class, 'all'])
->middleware('permission:' . PermissionEnum::READ_INTEGRATIONS->value)
->name('api.integrations.index');
// Slack API for getting slack channels list
$router->get('{notificationProvider}/channels', [Controllers\NotificationProviderController::class, 'channels']);
// Team actions. XXX: These all need moving out to their own controllers.
$router->group(['prefix' => 'organizations'], static function (Router $router): void {
$router->get('current', [TeamController::class, 'current']);
$router->group(['prefix' => '{team}', 'middleware' => ['teamMember']], static function (Router $router): void {
$router->get('/', [TeamController::class, 'show']);
$router->get('/categories', [TeamController::class, 'categories']);
$router->get('/stages', [TeamController::class, 'stages']);
$router->get('/users', [OrganizationMembersController::class, 'index'])
->name('organization.members.index');
$router
->get('/users/download', [OrganizationMembersController::class, 'download'])
->middleware('permission:' . PermissionEnum::MANAGE_USERS->value)
->name('organization.members.download');
$router->get('/licensed-roles', [OrganizationLicensesController::class, 'index'])
->middleware('permission:' . PermissionEnum::MANAGE_BILLING->value)
->name('organization.licensed-roles.index');
$router->get('/invitations', [TeamController::class, 'invitations']);
$router->get('/groups', [TeamController::class, 'groups']);
$router->delete('/groups/{group}', [TeamController::class, 'deleteGroup'])
->middleware(['permission:' . PermissionEnum::DELETE_TEAM->value])
->name('api.groups.delete');
$router->get('/job-titles', [TeamController::class, 'jobTitles']);
$router->get('/slugs', [TeamController::class, 'slugs']);
$router->put('/api-token', [TeamController::class, 'generateApiToken'])
->middleware(['permission:' . PermissionEnum::MANAGE_ORGANIZATION_SETTINGS->value]);
$router->get('/key-moments', [MomentController::class, 'all']);
});
});
// Internal Kiosk. This whole section will be moved out to a separate file
$router
->prefix('kiosk')
->middleware('can:kiosk,' . User::class)
->group(static function (Router $router): void {
// Partner actions.
$router->get('/partners', [PartnersController::class, 'index']);
// User actions.
$router->post('/users/search', [SearchController::class, 'performBasicSearch']);
// Team actions.
$router->prefix('organizations')->group(static function (Router $router): void {
$router->get('/', [OrganizationsController::class, 'show']);
$router->put('/{team}', [OrganizationController::class, 'edit'])
->name('kiosk.organizations.edit');
$router->get('/{team}/users', [OrganizationMembersController::class, 'index'])
->name('kiosk.organization.members.index');
$router->get('onboardable', [OnboardController::class, 'available']);
$router->delete('/{team}', [OrganizationsController::class, 'deactivateAccounts']);
});
// Automated reports
// api/v1/kiosk/automated-reports
$router->prefix('automated-reports')->group(static function (Router $router): void {
$router->get('/form-data', [AutomatedReportsController::class, 'getCreateForm']);
$router->get('/form-data/{reportUuid}', [AutomatedReportsController::class, 'getEditForm']);
$router->post('/filters', [AutomatedReportsController::class, 'getFilters']);
$router->post('/', [AutomatedReportsController::class, 'create']);
$router->put('/{reportUuid}', [AutomatedReportsController::class, 'update']);
$router->patch('/{reportUuid}', [AutomatedReportsController::class, 'partialUpdate']);
$router->get('/', [AutomatedReportsController::class, 'list']);
$router->get('/{reportUuid}', [AutomatedReportsController::class, 'get']);
$router->delete('/{reportUuid}', [AutomatedReportsController::class, 'delete']);
$router->post('/activities-count', [AutomatedReportsController::class, 'getActivitiesCount']);
$router->get('/{reportUuid}/reports-count', [AutomatedReportsController::class, 'getReportsCount']);
});
// Activity actions.
$router->post('/activity/search', [SearchController::class, 'performActivitySearch']);
$router->prefix('activity/{activity}')->group(static function (Router $router): void {
$router->post('check-playable', [SearchController::class, 'performActivityCheckPlayable']);
$router->post('reset-crm-log', [SearchController::class, 'performResetCrmLogActivity']);
$router->get('diarize-via-transcript', [KioskActivityController::class, 'diarizeViaTranscript']);
$router->post('diarize-via-transcript', [KioskActivityController::class, 'diarizeViaTranscript']);
$router->get('media-pipeline', [MediaPipelineController::class, 'getPipes']);
$router->post('media-pipeline', [MediaPipelineController::class, 'updatePipe']);
$router->post('language', [KioskActivityController::class, 'updateLanguage']);
$router->post('trim', [KioskActivityController::class, 'trimActivity']);
$router->get('troubleshoot', [KioskActivityController::class, 'troubleshootActivity']);
$router->get('transcription', [KioskActivityController::class, 'getTranscriptions']);
$router->post('speakers', [KioskActivityController::class, 'addSpeakers']);
$router->post('crm-f...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79493
|
2787
|
51
|
2026-05-28T06:31:47.455699+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949907455_m2.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project Files
Preview
Filter
Open in Find Tool Win Project Files
Preview
Filter
Open in Find Tool Window
api.php
api.php .../routes/api.php
Api.php .../vendor/google/apiclient-services/src/ApigeeRegistry/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceConsumerManagement/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceControl/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceManagement/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceNetworking/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceUsage/Api.php, class
Api.php .../vendor/twilio/sdk/src/Twilio/Rest/Api.php, class
Api.php .../vendor/spatie/flare-client-php/src/Api.php, class
Api.php .../vendor/google/protobuf/src/Google/Protobuf/Api.php, class
Api.php .../vendor/google/common-protos/src/Rpc/Context/AttributeContext/Api.php, class
Api.php .../vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/Api.php, class
Apigateway.php .../vendor/google/apiclient-services/src/Apigateway.php, class
Apigee.php .../vendor/google/apiclient-services/src/Apigee.php, class
APIhub.php .../vendor/google/apiclient-services/src/APIhub.php, class
… more
api.php .../routes/api.php
Api.php .../vendor/google/apiclient-services/src/ApigeeRegistry/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceConsumerManagement/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceControl/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceManagement/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceNetworking/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceUsage/Api.php, class
Api.php .../vendor/twilio/sdk/src/Twilio/Rest/Api.php, class
Api.php .../vendor/spatie/flare-client-php/src/Api.php, class
Api.php .../vendor/google/protobuf/src/Google/Protobuf/Api.php, class
Api.php .../vendor/google/common-protos/src/Rpc/Context/AttributeContext/Api.php, class
Api.php .../vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/Api.php, class
Apigateway.php .../vendor/google/apiclient-services/src/Apigateway.php, class
Apigee.php .../vendor/google/apiclient-services/src/Apigee.php, class
APIhub.php .../vendor/google/apiclient-services/src/APIhub.php, class
… more
routes/api.php
Open In Right Split...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project Files","depth":2,"bounds":{"left":0.6968085,"top":0.24181964,"width":0.03557181,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Preview","depth":2,"bounds":{"left":0.73238033,"top":0.24181964,"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":"Filter","depth":2,"bounds":{"left":0.74102396,"top":0.24181964,"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 in Find Tool Window","depth":2,"bounds":{"left":0.7496675,"top":0.24181964,"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":"AXTextField","text":"api.php","depth":1,"bounds":{"left":0.50232714,"top":0.27214685,"width":0.25598404,"height":0.023144454},"on_screen":true,"value":"api.php","role_description":"text field","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"api.php .../routes/api.php","depth":2,"bounds":{"left":0.4993351,"top":0.30407023,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ApigeeRegistry/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.3216281,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceConsumerManagement/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.33918595,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceControl/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.3567438,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceManagement/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.37430167,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceNetworking/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.39185953,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceUsage/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.4094174,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/twilio/sdk/src/Twilio/Rest/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.42697525,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/spatie/flare-client-php/src/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.4445331,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/protobuf/src/Google/Protobuf/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.46209097,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/common-protos/src/Rpc/Context/AttributeContext/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.47964883,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.49720672,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Apigateway.php .../vendor/google/apiclient-services/src/Apigateway.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.51476455,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Apigee.php .../vendor/google/apiclient-services/src/Apigee.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.5323224,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"APIhub.php .../vendor/google/apiclient-services/src/APIhub.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.54988027,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"… more","depth":2,"bounds":{"left":0.4993351,"top":0.5674381,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"api.php .../routes/api.php","depth":4,"bounds":{"left":0.4993351,"top":0.30407023,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ApigeeRegistry/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.3216281,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceConsumerManagement/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.33918595,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceControl/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.3567438,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceManagement/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.37430167,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceNetworking/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.39185953,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceUsage/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.4094174,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/twilio/sdk/src/Twilio/Rest/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.42697525,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/spatie/flare-client-php/src/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.4445331,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/protobuf/src/Google/Protobuf/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.46209097,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/common-protos/src/Rpc/Context/AttributeContext/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.47964883,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.49720672,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Apigateway.php .../vendor/google/apiclient-services/src/Apigateway.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.51476455,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Apigee.php .../vendor/google/apiclient-services/src/Apigee.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.5323224,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"APIhub.php .../vendor/google/apiclient-services/src/APIhub.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.54988027,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"… more","depth":4,"bounds":{"left":0.4993351,"top":0.5674381,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"routes/api.php","depth":1,"bounds":{"left":0.50598407,"top":0.75259376,"width":0.027260639,"height":0.013567438},"on_screen":true,"help_text":"routes/api.php","role_description":"text"},{"role":"AXLink","text":"Open In Right Split","depth":1,"bounds":{"left":0.71476066,"top":0.75259376,"width":0.03856383,"height":0.013567438},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-5025908619333727782
|
185459600388111307
|
typing_pause
|
accessibility
|
NULL
|
Project Files
Preview
Filter
Open in Find Tool Win Project Files
Preview
Filter
Open in Find Tool Window
api.php
api.php .../routes/api.php
Api.php .../vendor/google/apiclient-services/src/ApigeeRegistry/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceConsumerManagement/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceControl/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceManagement/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceNetworking/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceUsage/Api.php, class
Api.php .../vendor/twilio/sdk/src/Twilio/Rest/Api.php, class
Api.php .../vendor/spatie/flare-client-php/src/Api.php, class
Api.php .../vendor/google/protobuf/src/Google/Protobuf/Api.php, class
Api.php .../vendor/google/common-protos/src/Rpc/Context/AttributeContext/Api.php, class
Api.php .../vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/Api.php, class
Apigateway.php .../vendor/google/apiclient-services/src/Apigateway.php, class
Apigee.php .../vendor/google/apiclient-services/src/Apigee.php, class
APIhub.php .../vendor/google/apiclient-services/src/APIhub.php, class
… more
api.php .../routes/api.php
Api.php .../vendor/google/apiclient-services/src/ApigeeRegistry/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceConsumerManagement/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceControl/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceManagement/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceNetworking/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceUsage/Api.php, class
Api.php .../vendor/twilio/sdk/src/Twilio/Rest/Api.php, class
Api.php .../vendor/spatie/flare-client-php/src/Api.php, class
Api.php .../vendor/google/protobuf/src/Google/Protobuf/Api.php, class
Api.php .../vendor/google/common-protos/src/Rpc/Context/AttributeContext/Api.php, class
Api.php .../vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/Api.php, class
Apigateway.php .../vendor/google/apiclient-services/src/Apigateway.php, class
Apigee.php .../vendor/google/apiclient-services/src/Apigee.php, class
APIhub.php .../vendor/google/apiclient-services/src/APIhub.php, class
… more
routes/api.php
Open In Right Split...
|
79492
|
NULL
|
NULL
|
NULL
|
|
79492
|
2787
|
50
|
2026-05-28T06:31:46.440067+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949906440_m2.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project Files
Preview
Filter
Open in Find Tool Win Project Files
Preview
Filter
Open in Find Tool Window
api.p
api.php .../routes/api.php
Api.php .../vendor/google/apiclient-services/src/ApigeeRegistry/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceConsumerManagement/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceControl/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceManagement/Api.php, class
Api.php .../vendor/spatie/flare-client-php/src/Api.php, class
apigen.neon vendor/php-http/message
Api.php .../vendor/google/apiclient-services/src/ServiceNetworking/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceUsage/Api.php, class
Api.php .../vendor/twilio/sdk/src/Twilio/Rest/Api.php, class
Api.php .../vendor/google/protobuf/src/Google/Protobuf/Api.php, class
Api.php .../vendor/google/common-protos/src/Rpc/Context/AttributeContext/Api.php, class
Api.php .../vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/Api.php, class
Apigateway.php .../vendor/google/apiclient-services/src/Apigateway.php, class
Apigee.php .../vendor/google/apiclient-services/src/Apigee.php, class
api.php .../routes/api.php
Api.php .../vendor/google/apiclient-services/src/ApigeeRegistry/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceConsumerManagement/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceControl/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceManagement/Api.php, class
Api.php .../vendor/spatie/flare-client-php/src/Api.php, class
apigen.neon vendor/php-http/message
Api.php .../vendor/google/apiclient-services/src/ServiceNetworking/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceUsage/Api.php, class
Api.php .../vendor/twilio/sdk/src/Twilio/Rest/Api.php, class
Api.php .../vendor/google/protobuf/src/Google/Protobuf/Api.php, class
Api.php .../vendor/google/common-protos/src/Rpc/Context/AttributeContext/Api.php, class...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project Files","depth":2,"bounds":{"left":0.6968085,"top":0.24181964,"width":0.03557181,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Preview","depth":2,"bounds":{"left":0.73238033,"top":0.24181964,"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":"Filter","depth":2,"bounds":{"left":0.74102396,"top":0.24181964,"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 in Find Tool Window","depth":2,"bounds":{"left":0.7496675,"top":0.24181964,"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":"AXTextField","text":"api.p","depth":1,"bounds":{"left":0.50232714,"top":0.27214685,"width":0.25598404,"height":0.023144454},"on_screen":true,"value":"api.p","role_description":"text field","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"api.php .../routes/api.php","depth":2,"bounds":{"left":0.4993351,"top":0.30407023,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ApigeeRegistry/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.3216281,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceConsumerManagement/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.33918595,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceControl/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.3567438,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceManagement/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.37430167,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/spatie/flare-client-php/src/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.39185953,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"apigen.neon vendor/php-http/message","depth":2,"bounds":{"left":0.4993351,"top":0.4094174,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceNetworking/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.42697525,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceUsage/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.4445331,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/twilio/sdk/src/Twilio/Rest/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.46209097,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/protobuf/src/Google/Protobuf/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.47964883,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/common-protos/src/Rpc/Context/AttributeContext/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.49720672,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/Api.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.51476455,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Apigateway.php .../vendor/google/apiclient-services/src/Apigateway.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.5323224,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Apigee.php .../vendor/google/apiclient-services/src/Apigee.php, class","depth":2,"bounds":{"left":0.4993351,"top":0.54988027,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"api.php .../routes/api.php","depth":4,"bounds":{"left":0.4993351,"top":0.30407023,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ApigeeRegistry/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.3216281,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceConsumerManagement/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.33918595,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceControl/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.3567438,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceManagement/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.37430167,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/spatie/flare-client-php/src/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.39185953,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"apigen.neon vendor/php-http/message","depth":4,"bounds":{"left":0.4993351,"top":0.4094174,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceNetworking/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.42697525,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/apiclient-services/src/ServiceUsage/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.4445331,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/twilio/sdk/src/Twilio/Rest/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.46209097,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/protobuf/src/Google/Protobuf/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.47964883,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Api.php .../vendor/google/common-protos/src/Rpc/Context/AttributeContext/Api.php, class","depth":4,"bounds":{"left":0.4993351,"top":0.49720672,"width":0.26196808,"height":0.017557861},"on_screen":true,"role_description":"text"}]...
|
-1910102756766401875
|
-9109684157165757477
|
typing_pause
|
accessibility
|
NULL
|
Project Files
Preview
Filter
Open in Find Tool Win Project Files
Preview
Filter
Open in Find Tool Window
api.p
api.php .../routes/api.php
Api.php .../vendor/google/apiclient-services/src/ApigeeRegistry/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceConsumerManagement/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceControl/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceManagement/Api.php, class
Api.php .../vendor/spatie/flare-client-php/src/Api.php, class
apigen.neon vendor/php-http/message
Api.php .../vendor/google/apiclient-services/src/ServiceNetworking/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceUsage/Api.php, class
Api.php .../vendor/twilio/sdk/src/Twilio/Rest/Api.php, class
Api.php .../vendor/google/protobuf/src/Google/Protobuf/Api.php, class
Api.php .../vendor/google/common-protos/src/Rpc/Context/AttributeContext/Api.php, class
Api.php .../vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/Api.php, class
Apigateway.php .../vendor/google/apiclient-services/src/Apigateway.php, class
Apigee.php .../vendor/google/apiclient-services/src/Apigee.php, class
api.php .../routes/api.php
Api.php .../vendor/google/apiclient-services/src/ApigeeRegistry/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceConsumerManagement/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceControl/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceManagement/Api.php, class
Api.php .../vendor/spatie/flare-client-php/src/Api.php, class
apigen.neon vendor/php-http/message
Api.php .../vendor/google/apiclient-services/src/ServiceNetworking/Api.php, class
Api.php .../vendor/google/apiclient-services/src/ServiceUsage/Api.php, class
Api.php .../vendor/twilio/sdk/src/Twilio/Rest/Api.php, class
Api.php .../vendor/google/protobuf/src/Google/Protobuf/Api.php, class
Api.php .../vendor/google/common-protos/src/Rpc/Context/AttributeContext/Api.php, class...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79491
|
2787
|
49
|
2026-05-28T06:31:44.266219+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949904266_m2.jpg...
|
PhpStorm
|
faVsco.js – Field.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
42
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models\Crm;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Jiminny\Component\Eloquent\Builder;
use Jiminny\Models\Ai\CrmTemplateField;
use Jiminny\Models\Model;
use Jiminny\Models\Playbook;
use Jiminny\Services\Crm\CrmObjects\FieldReadonlyConstants;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
/**
* Jiminny\Models\Crm\Field
*
* @property int $id
* @property mixed|null $uuid
* @property int $crm_configuration_id
* @property string $crm_provider_id
* @property string $label
* @property string|null $description
* @property string $type
* @property int|null $length
* @property string|null $default_value
* @property string $object_type
* @property bool $is_selectable
* @property bool $is_mandatory
* @property bool $is_filterable
* @property bool $is_indexable
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Jiminny\Models\Crm\Configuration $configuration
* @property-read \Jiminny\Models\Crm\Configuration $crm
* @property-read Collection<int, \Jiminny\Models\Crm\FieldData> $data
* @property-read int|null $data_count
* @property-read Collection<int, \Jiminny\Models\Crm\LayoutEntity> $entities
* @property-read int|null $entities_count
* @property-read string $id_string
* @property-read Collection<int, \Jiminny\Models\Crm\FieldValue> $values
* @property-read int|null $values_count
*
* @method static Builder|Field chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\Crm\FieldFactory factory(...$parameters)
* @method static Builder|Field idOrUuId($idOrUuid, bool $first = true)
* @method static Builder|Field indexable()
* @method static Builder|Field newModelQuery()
* @method static Builder|Field newQuery()
* @method static Builder|Field query()
* @method static Builder|Field tasks()
* @method static Builder|Field uuid(string $uuid, bool $first = true)
* @method static Builder|Field whereCreatedAt($value)
* @method static Builder|Field whereCrmConfigurationId($value)
* @method static Builder|Field whereCrmProviderId($value)
* @method static Builder|Field whereDefaultValue($value)
* @method static Builder|Field whereDescription($value)
* @method static Builder|Field whereId($value)
* @method static Builder|Field whereIsFilterable($value)
* @method static Builder|Field whereIsIndexable($value)
* @method static Builder|Field whereIsMandatory($value)
* @method static Builder|Field whereIsSelectable($value)
* @method static Builder|Field whereLabel($value)
* @method static Builder|Field whereLength($value)
* @method static Builder|Field whereObjectType($value)
* @method static Builder|Field whereType($value)
* @method static Builder|Field whereUpdatedAt($value)
* @method static Builder|Field whereUuid($value)
*
* @mixin \Eloquent
*/
class Field extends Model
{
use HasFactory;
use RequiresUUID;
use Enums;
public const int NAME_MAX_LENGTH = 128;
public const int LABEL_MAX_LENGTH = 255;
public const int DESCRIPTION_MAX_LENGTH = 191;
public const string TYPE_MULTIPICKLIST = 'multi-picklist';
// Not yet supported
public const string TYPE_PERCENT = 'percent';
public const string TYPE_PICKLIST = 'picklist';
public const string TYPE_NUMBER = 'number';
public const string TYPE_CURRENCY = 'currency';
public const string TYPE_BOOLEAN = 'boolean';
public const string TYPE_TEXT = 'text';
public const string TYPE_TEXTAREA = 'textarea';
public const string TYPE_EMAIL = 'email';
public const string TYPE_PHONE = 'phone';
public const string TYPE_URL = 'url';
public const string TYPE_DATE = 'date';
public const string TYPE_TIME = 'time';
public const string TYPE_DATETIME = 'datetime';
public const string TYPE_UNSUPPORTED = 'unsupported';
public const string OBJECT_LEAD = 'lead';
public const string OBJECT_ACCOUNT = 'account';
public const string OBJECT_CONTACT = 'contact';
public const string OBJECT_OPPORTUNITY = 'opportunity';
public const string OBJECT_TASK = 'task';
public const string OBJECT_EVENT = 'event';
public const string OBJECT_CALL = 'call';
public const string OBJECT_MEETING = 'meeting';
public const array BUSINESS_TYPE_FIELDS = [
Configuration::PROVIDER_SALESFORCE => 'Type',
Configuration::PROVIDER_HUBSPOT => 'dealtype',
];
public const array PIPELINE_TYPE_FIELDS = [
Configuration::PROVIDER_HUBSPOT => 'pipeline',
];
public const array STAGE_TYPE_FIELDS = [
Configuration::PROVIDER_SALESFORCE => 'StageName',
Configuration::PROVIDER_HUBSPOT => 'dealstage',
Configuration::PROVIDER_CLOSE => 'status_id',
Configuration::PROVIDER_BULLHORN => 'status',
Configuration::PROVIDER_PIPEDRIVE => 'stage_id',
Configuration::PROVIDER_COPPER => 'pipeline_stage_id',
];
public static $enumTypes = [
self::TYPE_PICKLIST,
self::TYPE_NUMBER,
self::TYPE_CURRENCY,
self::TYPE_BOOLEAN,
self::TYPE_TEXT,
self::TYPE_TEXTAREA,
self::TYPE_EMAIL,
self::TYPE_PHONE,
self::TYPE_URL,
self::TYPE_DATE,
self::TYPE_TIME,
self::TYPE_DATETIME,
self::TYPE_UNSUPPORTED,
];
public static $enumObjectTypes = [
self::OBJECT_LEAD,
self::OBJECT_ACCOUNT,
self::OBJECT_CONTACT,
self::OBJECT_OPPORTUNITY,
self::OBJECT_TASK,
self::OBJECT_EVENT,
];
protected $table = 'crm_fields';
protected $fillable = [
'crm_configuration_id',
'crm_provider_id',
'object_type',
'type',
'label',
'description',
'is_selectable',
'is_mandatory',
'length',
'default_value',
'is_indexable',
'is_filterable',
'is_readonly',
];
protected $appends = [
'id_string',
];
protected $hidden = [
'uuid',
'id',
'crm_configuration_id',
];
protected function casts(): array
{
return [
'is_selectable' => 'boolean',
'is_mandatory' => 'boolean',
'is_indexable' => 'boolean',
'is_filterable' => 'boolean',
];
}
public function configuration(): BelongsTo
{
return $this->belongsTo(Configuration::class, 'crm_configuration_id');
}
public function entities(): HasMany
{
return $this->hasMany(LayoutEntity::class, 'crm_field_id');
}
public function getEntities(): Collection
{
/** @var Collection<LayoutEntity> $entities */
$entities = $this->getAttribute('entities');
return $entities;
}
public function values(): HasMany
{
return $this->hasMany(FieldValue::class, 'crm_field_id')->orderBy('sequence');
}
public function getLabel(): string
{
return $this->getAttribute('label');
}
public function getType(): string
{
return $this->getAttribute('type');
}
public function getObjectType(): string
{
/** @var string */
return $this->getAttribute('object_type');
}
public function getCrmProviderId(): string
{
/** @var string */
return $this->getAttribute('crm_provider_id');
}
public function getValues(): Collection
{
return $this->getAttribute('values');
}
public function isIndexable(): bool
{
return $this->getAttribute('is_indexable');
}
public function isFilterable(): bool
{
return $this->getAttribute('is_filterable');
}
public function getId(): int
{
/** @var int */
return $this->getAttribute('id');
}
public function hasDescription(): bool
{
return $this->getAttribute('description') !== null;
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function data()
{
return $this->hasMany(FieldData::class, 'crm_field_id');
}
public function crm(): BelongsTo
{
return $this->belongsTo(Configuration::class, 'crm_configuration_id');
}
#[Scope]
protected function indexable($query)
{
return $query->where('is_indexable', 1);
}
#[Scope]
protected function tasks($query)
{
return $query->where('object_type', self::OBJECT_TASK);
}
public function isBusinessType(): bool
{
return in_array($this->getCrmProviderId(), self::BUSINESS_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function isStageField(): bool
{
return in_array($this->getCrmProviderId(), self::STAGE_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function isPipelineField(): bool
{
return in_array($this->getCrmProviderId(), self::PIPELINE_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function getUuid(): string
{
return $this->getAttribute('id_string');
}
public function getCrmConfiguration(): Configuration
{
return $this->getAttribute('crm');
}
public function getCrmConfigurationId(): int
{
return $this->getAttribute('crm_configuration_id');
}
/**
* Currently implemented only for Opportunity fields
*/
public function isReadOnly(): bool
{
// The CRM Field metadata should always be first to be taken into consideration.
if ($this->getIsReadonly()) {
return true;
}
if ($this->getObjectType() !== self::OBJECT_OPPORTUNITY) {
return false;
}
if ($this->isPipelineField()) {
return true;
}
if ($this->getType() === Field::TYPE_UNSUPPORTED) {
return true;
}
if ($this->getCrmConfiguration()->getProviderName() === Configuration::PROVIDER_INTEGRATION_APP) {
$fieldDefinitions = new CrmFieldDefinitionsManager();
return $fieldDefinitions->isReadOnly($this->getCrmProviderId(), self::OBJECT_OPPORTUNITY);
}
return false;
}
public function isPicklist(): bool
{
return in_array($this->getType(), [self::TYPE_PICKLIST, self::TYPE_MULTIPICKLIST]);
}
public function getLength(): ?int
{
return $this->getAttribute('length');
}
public function getDefaultValue(): ?string
{
return $this->getAttribute('default_value');
}
public function setIsReadonly(int $isReadonly): void
{
$this->setAttribute('is_readonly', $isReadonly);
}
public function getIsReadonly(): bool
{
return $this->getAttribute('is_readonly') !== FieldReadonlyConstants::FIELD_IS_UPDATABLE;
}
public function getEntityName(): string
{
return ucfirst($this->getObjectType()) . '.' . $this->getCrmProviderId();
}
public function crmTemplateFields(): HasMany
{
return $this->hasMany(CrmTemplateField::class, 'crm_field_id');
}
public function playbooks(): HasMany
{
return $this->hasMany(Playbook::class, 'activity_field_id');
}
public function getPlaybooks(): Collection
{
return $this->getAttribute('playbooks');
}
}
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
21
1
18
2
6
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id
where u.team_id = 1;
SELECT * FROM social_accounts WHERE sociable_id = 1635;
SELECT * FROM users WHERE id = 1635;
select * from teams where id = 1;
select * from users where team_id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role;
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
SELECT * FROM automated_reports where id = 71;
SELECT * FROM automated_report_results where report_id = 71;
UPDATE automated_reports set playbook_categories = NULL where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT `automated_report_results`.* FROM `automated_report_results`
INNER JOIN `automated_reports`
ON `automated_report_results`.`report_id` = `automated_reports`.`id`
WHERE 1=1
AND `automated_report_results`.`generated_at` IS NOT NULL
# AND `automated_report_results`.`sent_at` IS NOT NULL
AND `automated_reports`.`team_id` = 1
AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$."users"')
;
SELECT * FROM automated_reports where id = 67;
SELECT * FROM automated_reports where id = 42;
SELECT * FROM users WHERE id = 143; # group 28
select * from teams where id = 3143;
select * from crm_configurations where id = 500;
select * from users where name = 'Integration Account'; # 1695
SELECT * FROM social_accounts WHERE sociable_id = 1695;
select * from activities where crm_configuration_id = 39
and recording_state = 'recorded' and duration > 60
and status = 'completed' and actual_start_time >= '2025-12-01';
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;
select * from leads;
SELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003
SELECT * FROM activities WHERE id IN (16,422003);
SELECT * FROM activities where status = 'failed';
SELECT * FROM tracks WHERE activity_id = 422003;
SELECT
a.*
FROM activities a
JOIN users u ON a.user_id = u.id
WHERE
a.status = 'completed'
AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid
AND a.deleted_at IS NULL
AND EXISTS (
SELECT 1 FROM tracks t
WHERE t.activity_id = a.id
AND t.type IN ('audio', 'video')
)
ORDER BY a.actual_start_time DESC
LIMIT 25;
select * from teams where id = 19;
select * from crm_configurations where provider = 'pipedrive';
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 = 19 and sa.provider = 'pipedrive';
SELECT * FROM social_accounts WHERE id = 1116;
UPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',
provider_refresh_token = '5034113:[TELEGRAM_TOKEN]b2bfc',
expires = 1779091997,
state = 'connected'
WHERE id = 1116;
"provider_user_token": "v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA",
"provider_refresh_token": "5034113:[TELEGRAM_TOKEN]b2bfc",
"expires": 1779091997,
select * from crm_field_values;
select * from crm_fields where type = 'multi-picklist';
SELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
SELECT * FROM crm_fields WHERE id = 3014; # 1885
SELECT * FROM crm_field_values WHERE crm_field_id = 3014;
Project...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09740692,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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.8374335,"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":"TextRelayServiceTest","depth":6,"bounds":{"left":0.85272604,"top":0.019952115,"width":0.062832445,"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 'TextRelayServiceTest'","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 'TextRelayServiceTest'","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":"42","depth":4,"bounds":{"left":0.375,"top":0.10055866,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.38730052,"top":0.10055866,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39694148,"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.40425533,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Models\\Crm;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Jiminny\\Component\\Eloquent\\Builder;\nuse Jiminny\\Models\\Ai\\CrmTemplateField;\nuse Jiminny\\Models\\Model;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Services\\Crm\\CrmObjects\\FieldReadonlyConstants;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\n\n/**\n * Jiminny\\Models\\Crm\\Field\n *\n * @property int $id\n * @property mixed|null $uuid\n * @property int $crm_configuration_id\n * @property string $crm_provider_id\n * @property string $label\n * @property string|null $description\n * @property string $type\n * @property int|null $length\n * @property string|null $default_value\n * @property string $object_type\n * @property bool $is_selectable\n * @property bool $is_mandatory\n * @property bool $is_filterable\n * @property bool $is_indexable\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property-read \\Jiminny\\Models\\Crm\\Configuration $configuration\n * @property-read \\Jiminny\\Models\\Crm\\Configuration $crm\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\FieldData> $data\n * @property-read int|null $data_count\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\LayoutEntity> $entities\n * @property-read int|null $entities_count\n * @property-read string $id_string\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\FieldValue> $values\n * @property-read int|null $values_count\n *\n * @method static Builder|Field chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\Crm\\FieldFactory factory(...$parameters)\n * @method static Builder|Field idOrUuId($idOrUuid, bool $first = true)\n * @method static Builder|Field indexable()\n * @method static Builder|Field newModelQuery()\n * @method static Builder|Field newQuery()\n * @method static Builder|Field query()\n * @method static Builder|Field tasks()\n * @method static Builder|Field uuid(string $uuid, bool $first = true)\n * @method static Builder|Field whereCreatedAt($value)\n * @method static Builder|Field whereCrmConfigurationId($value)\n * @method static Builder|Field whereCrmProviderId($value)\n * @method static Builder|Field whereDefaultValue($value)\n * @method static Builder|Field whereDescription($value)\n * @method static Builder|Field whereId($value)\n * @method static Builder|Field whereIsFilterable($value)\n * @method static Builder|Field whereIsIndexable($value)\n * @method static Builder|Field whereIsMandatory($value)\n * @method static Builder|Field whereIsSelectable($value)\n * @method static Builder|Field whereLabel($value)\n * @method static Builder|Field whereLength($value)\n * @method static Builder|Field whereObjectType($value)\n * @method static Builder|Field whereType($value)\n * @method static Builder|Field whereUpdatedAt($value)\n * @method static Builder|Field whereUuid($value)\n *\n * @mixin \\Eloquent\n */\nclass Field extends Model\n{\n use HasFactory;\n\n use RequiresUUID;\n use Enums;\n\n public const int NAME_MAX_LENGTH = 128;\n public const int LABEL_MAX_LENGTH = 255;\n public const int DESCRIPTION_MAX_LENGTH = 191;\n\n public const string TYPE_MULTIPICKLIST = 'multi-picklist';\n // Not yet supported\n public const string TYPE_PERCENT = 'percent';\n\n public const string TYPE_PICKLIST = 'picklist';\n public const string TYPE_NUMBER = 'number';\n public const string TYPE_CURRENCY = 'currency';\n public const string TYPE_BOOLEAN = 'boolean';\n public const string TYPE_TEXT = 'text';\n public const string TYPE_TEXTAREA = 'textarea';\n public const string TYPE_EMAIL = 'email';\n public const string TYPE_PHONE = 'phone';\n public const string TYPE_URL = 'url';\n public const string TYPE_DATE = 'date';\n public const string TYPE_TIME = 'time';\n public const string TYPE_DATETIME = 'datetime';\n public const string TYPE_UNSUPPORTED = 'unsupported';\n\n public const string OBJECT_LEAD = 'lead';\n public const string OBJECT_ACCOUNT = 'account';\n public const string OBJECT_CONTACT = 'contact';\n public const string OBJECT_OPPORTUNITY = 'opportunity';\n public const string OBJECT_TASK = 'task';\n public const string OBJECT_EVENT = 'event';\n public const string OBJECT_CALL = 'call';\n public const string OBJECT_MEETING = 'meeting';\n\n public const array BUSINESS_TYPE_FIELDS = [\n Configuration::PROVIDER_SALESFORCE => 'Type',\n Configuration::PROVIDER_HUBSPOT => 'dealtype',\n ];\n\n public const array PIPELINE_TYPE_FIELDS = [\n Configuration::PROVIDER_HUBSPOT => 'pipeline',\n ];\n\n public const array STAGE_TYPE_FIELDS = [\n Configuration::PROVIDER_SALESFORCE => 'StageName',\n Configuration::PROVIDER_HUBSPOT => 'dealstage',\n Configuration::PROVIDER_CLOSE => 'status_id',\n Configuration::PROVIDER_BULLHORN => 'status',\n Configuration::PROVIDER_PIPEDRIVE => 'stage_id',\n Configuration::PROVIDER_COPPER => 'pipeline_stage_id',\n ];\n\n public static $enumTypes = [\n self::TYPE_PICKLIST,\n self::TYPE_NUMBER,\n self::TYPE_CURRENCY,\n self::TYPE_BOOLEAN,\n self::TYPE_TEXT,\n self::TYPE_TEXTAREA,\n self::TYPE_EMAIL,\n self::TYPE_PHONE,\n self::TYPE_URL,\n self::TYPE_DATE,\n self::TYPE_TIME,\n self::TYPE_DATETIME,\n self::TYPE_UNSUPPORTED,\n ];\n\n public static $enumObjectTypes = [\n self::OBJECT_LEAD,\n self::OBJECT_ACCOUNT,\n self::OBJECT_CONTACT,\n self::OBJECT_OPPORTUNITY,\n self::OBJECT_TASK,\n self::OBJECT_EVENT,\n ];\n\n protected $table = 'crm_fields';\n\n protected $fillable = [\n 'crm_configuration_id',\n 'crm_provider_id',\n 'object_type',\n 'type',\n 'label',\n 'description',\n 'is_selectable',\n 'is_mandatory',\n 'length',\n 'default_value',\n 'is_indexable',\n 'is_filterable',\n 'is_readonly',\n ];\n\n protected $appends = [\n 'id_string',\n ];\n\n protected $hidden = [\n 'uuid',\n 'id',\n 'crm_configuration_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'is_selectable' => 'boolean',\n 'is_mandatory' => 'boolean',\n 'is_indexable' => 'boolean',\n 'is_filterable' => 'boolean',\n ];\n }\n\n public function configuration(): BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function entities(): HasMany\n {\n return $this->hasMany(LayoutEntity::class, 'crm_field_id');\n }\n\n public function getEntities(): Collection\n {\n /** @var Collection<LayoutEntity> $entities */\n $entities = $this->getAttribute('entities');\n\n return $entities;\n }\n\n public function values(): HasMany\n {\n return $this->hasMany(FieldValue::class, 'crm_field_id')->orderBy('sequence');\n }\n\n public function getLabel(): string\n {\n return $this->getAttribute('label');\n }\n\n public function getType(): string\n {\n return $this->getAttribute('type');\n }\n\n public function getObjectType(): string\n {\n /** @var string */\n return $this->getAttribute('object_type');\n }\n\n public function getCrmProviderId(): string\n {\n /** @var string */\n return $this->getAttribute('crm_provider_id');\n }\n\n public function getValues(): Collection\n {\n return $this->getAttribute('values');\n }\n\n public function isIndexable(): bool\n {\n return $this->getAttribute('is_indexable');\n }\n\n public function isFilterable(): bool\n {\n return $this->getAttribute('is_filterable');\n }\n\n public function getId(): int\n {\n /** @var int */\n return $this->getAttribute('id');\n }\n\n public function hasDescription(): bool\n {\n return $this->getAttribute('description') !== null;\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function data()\n {\n return $this->hasMany(FieldData::class, 'crm_field_id');\n }\n\n public function crm(): BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n #[Scope]\n protected function indexable($query)\n {\n return $query->where('is_indexable', 1);\n }\n\n #[Scope]\n protected function tasks($query)\n {\n return $query->where('object_type', self::OBJECT_TASK);\n }\n\n public function isBusinessType(): bool\n {\n return in_array($this->getCrmProviderId(), self::BUSINESS_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function isStageField(): bool\n {\n return in_array($this->getCrmProviderId(), self::STAGE_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function isPipelineField(): bool\n {\n return in_array($this->getCrmProviderId(), self::PIPELINE_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getCrmConfiguration(): Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function getCrmConfigurationId(): int\n {\n return $this->getAttribute('crm_configuration_id');\n }\n\n /**\n * Currently implemented only for Opportunity fields\n */\n public function isReadOnly(): bool\n {\n // The CRM Field metadata should always be first to be taken into consideration.\n if ($this->getIsReadonly()) {\n return true;\n }\n\n if ($this->getObjectType() !== self::OBJECT_OPPORTUNITY) {\n return false;\n }\n\n if ($this->isPipelineField()) {\n return true;\n }\n\n if ($this->getType() === Field::TYPE_UNSUPPORTED) {\n return true;\n }\n\n if ($this->getCrmConfiguration()->getProviderName() === Configuration::PROVIDER_INTEGRATION_APP) {\n $fieldDefinitions = new CrmFieldDefinitionsManager();\n\n return $fieldDefinitions->isReadOnly($this->getCrmProviderId(), self::OBJECT_OPPORTUNITY);\n }\n\n return false;\n }\n\n public function isPicklist(): bool\n {\n return in_array($this->getType(), [self::TYPE_PICKLIST, self::TYPE_MULTIPICKLIST]);\n }\n\n public function getLength(): ?int\n {\n return $this->getAttribute('length');\n }\n\n public function getDefaultValue(): ?string\n {\n return $this->getAttribute('default_value');\n }\n\n public function setIsReadonly(int $isReadonly): void\n {\n $this->setAttribute('is_readonly', $isReadonly);\n }\n\n public function getIsReadonly(): bool\n {\n return $this->getAttribute('is_readonly') !== FieldReadonlyConstants::FIELD_IS_UPDATABLE;\n }\n\n public function getEntityName(): string\n {\n return ucfirst($this->getObjectType()) . '.' . $this->getCrmProviderId();\n }\n\n public function crmTemplateFields(): HasMany\n {\n return $this->hasMany(CrmTemplateField::class, 'crm_field_id');\n }\n\n public function playbooks(): HasMany\n {\n return $this->hasMany(Playbook::class, 'activity_field_id');\n }\n\n public function getPlaybooks(): Collection\n {\n return $this->getAttribute('playbooks');\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Models\\Crm;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Jiminny\\Component\\Eloquent\\Builder;\nuse Jiminny\\Models\\Ai\\CrmTemplateField;\nuse Jiminny\\Models\\Model;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Services\\Crm\\CrmObjects\\FieldReadonlyConstants;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\n\n/**\n * Jiminny\\Models\\Crm\\Field\n *\n * @property int $id\n * @property mixed|null $uuid\n * @property int $crm_configuration_id\n * @property string $crm_provider_id\n * @property string $label\n * @property string|null $description\n * @property string $type\n * @property int|null $length\n * @property string|null $default_value\n * @property string $object_type\n * @property bool $is_selectable\n * @property bool $is_mandatory\n * @property bool $is_filterable\n * @property bool $is_indexable\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property-read \\Jiminny\\Models\\Crm\\Configuration $configuration\n * @property-read \\Jiminny\\Models\\Crm\\Configuration $crm\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\FieldData> $data\n * @property-read int|null $data_count\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\LayoutEntity> $entities\n * @property-read int|null $entities_count\n * @property-read string $id_string\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\FieldValue> $values\n * @property-read int|null $values_count\n *\n * @method static Builder|Field chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\Crm\\FieldFactory factory(...$parameters)\n * @method static Builder|Field idOrUuId($idOrUuid, bool $first = true)\n * @method static Builder|Field indexable()\n * @method static Builder|Field newModelQuery()\n * @method static Builder|Field newQuery()\n * @method static Builder|Field query()\n * @method static Builder|Field tasks()\n * @method static Builder|Field uuid(string $uuid, bool $first = true)\n * @method static Builder|Field whereCreatedAt($value)\n * @method static Builder|Field whereCrmConfigurationId($value)\n * @method static Builder|Field whereCrmProviderId($value)\n * @method static Builder|Field whereDefaultValue($value)\n * @method static Builder|Field whereDescription($value)\n * @method static Builder|Field whereId($value)\n * @method static Builder|Field whereIsFilterable($value)\n * @method static Builder|Field whereIsIndexable($value)\n * @method static Builder|Field whereIsMandatory($value)\n * @method static Builder|Field whereIsSelectable($value)\n * @method static Builder|Field whereLabel($value)\n * @method static Builder|Field whereLength($value)\n * @method static Builder|Field whereObjectType($value)\n * @method static Builder|Field whereType($value)\n * @method static Builder|Field whereUpdatedAt($value)\n * @method static Builder|Field whereUuid($value)\n *\n * @mixin \\Eloquent\n */\nclass Field extends Model\n{\n use HasFactory;\n\n use RequiresUUID;\n use Enums;\n\n public const int NAME_MAX_LENGTH = 128;\n public const int LABEL_MAX_LENGTH = 255;\n public const int DESCRIPTION_MAX_LENGTH = 191;\n\n public const string TYPE_MULTIPICKLIST = 'multi-picklist';\n // Not yet supported\n public const string TYPE_PERCENT = 'percent';\n\n public const string TYPE_PICKLIST = 'picklist';\n public const string TYPE_NUMBER = 'number';\n public const string TYPE_CURRENCY = 'currency';\n public const string TYPE_BOOLEAN = 'boolean';\n public const string TYPE_TEXT = 'text';\n public const string TYPE_TEXTAREA = 'textarea';\n public const string TYPE_EMAIL = 'email';\n public const string TYPE_PHONE = 'phone';\n public const string TYPE_URL = 'url';\n public const string TYPE_DATE = 'date';\n public const string TYPE_TIME = 'time';\n public const string TYPE_DATETIME = 'datetime';\n public const string TYPE_UNSUPPORTED = 'unsupported';\n\n public const string OBJECT_LEAD = 'lead';\n public const string OBJECT_ACCOUNT = 'account';\n public const string OBJECT_CONTACT = 'contact';\n public const string OBJECT_OPPORTUNITY = 'opportunity';\n public const string OBJECT_TASK = 'task';\n public const string OBJECT_EVENT = 'event';\n public const string OBJECT_CALL = 'call';\n public const string OBJECT_MEETING = 'meeting';\n\n public const array BUSINESS_TYPE_FIELDS = [\n Configuration::PROVIDER_SALESFORCE => 'Type',\n Configuration::PROVIDER_HUBSPOT => 'dealtype',\n ];\n\n public const array PIPELINE_TYPE_FIELDS = [\n Configuration::PROVIDER_HUBSPOT => 'pipeline',\n ];\n\n public const array STAGE_TYPE_FIELDS = [\n Configuration::PROVIDER_SALESFORCE => 'StageName',\n Configuration::PROVIDER_HUBSPOT => 'dealstage',\n Configuration::PROVIDER_CLOSE => 'status_id',\n Configuration::PROVIDER_BULLHORN => 'status',\n Configuration::PROVIDER_PIPEDRIVE => 'stage_id',\n Configuration::PROVIDER_COPPER => 'pipeline_stage_id',\n ];\n\n public static $enumTypes = [\n self::TYPE_PICKLIST,\n self::TYPE_NUMBER,\n self::TYPE_CURRENCY,\n self::TYPE_BOOLEAN,\n self::TYPE_TEXT,\n self::TYPE_TEXTAREA,\n self::TYPE_EMAIL,\n self::TYPE_PHONE,\n self::TYPE_URL,\n self::TYPE_DATE,\n self::TYPE_TIME,\n self::TYPE_DATETIME,\n self::TYPE_UNSUPPORTED,\n ];\n\n public static $enumObjectTypes = [\n self::OBJECT_LEAD,\n self::OBJECT_ACCOUNT,\n self::OBJECT_CONTACT,\n self::OBJECT_OPPORTUNITY,\n self::OBJECT_TASK,\n self::OBJECT_EVENT,\n ];\n\n protected $table = 'crm_fields';\n\n protected $fillable = [\n 'crm_configuration_id',\n 'crm_provider_id',\n 'object_type',\n 'type',\n 'label',\n 'description',\n 'is_selectable',\n 'is_mandatory',\n 'length',\n 'default_value',\n 'is_indexable',\n 'is_filterable',\n 'is_readonly',\n ];\n\n protected $appends = [\n 'id_string',\n ];\n\n protected $hidden = [\n 'uuid',\n 'id',\n 'crm_configuration_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'is_selectable' => 'boolean',\n 'is_mandatory' => 'boolean',\n 'is_indexable' => 'boolean',\n 'is_filterable' => 'boolean',\n ];\n }\n\n public function configuration(): BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function entities(): HasMany\n {\n return $this->hasMany(LayoutEntity::class, 'crm_field_id');\n }\n\n public function getEntities(): Collection\n {\n /** @var Collection<LayoutEntity> $entities */\n $entities = $this->getAttribute('entities');\n\n return $entities;\n }\n\n public function values(): HasMany\n {\n return $this->hasMany(FieldValue::class, 'crm_field_id')->orderBy('sequence');\n }\n\n public function getLabel(): string\n {\n return $this->getAttribute('label');\n }\n\n public function getType(): string\n {\n return $this->getAttribute('type');\n }\n\n public function getObjectType(): string\n {\n /** @var string */\n return $this->getAttribute('object_type');\n }\n\n public function getCrmProviderId(): string\n {\n /** @var string */\n return $this->getAttribute('crm_provider_id');\n }\n\n public function getValues(): Collection\n {\n return $this->getAttribute('values');\n }\n\n public function isIndexable(): bool\n {\n return $this->getAttribute('is_indexable');\n }\n\n public function isFilterable(): bool\n {\n return $this->getAttribute('is_filterable');\n }\n\n public function getId(): int\n {\n /** @var int */\n return $this->getAttribute('id');\n }\n\n public function hasDescription(): bool\n {\n return $this->getAttribute('description') !== null;\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function data()\n {\n return $this->hasMany(FieldData::class, 'crm_field_id');\n }\n\n public function crm(): BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n #[Scope]\n protected function indexable($query)\n {\n return $query->where('is_indexable', 1);\n }\n\n #[Scope]\n protected function tasks($query)\n {\n return $query->where('object_type', self::OBJECT_TASK);\n }\n\n public function isBusinessType(): bool\n {\n return in_array($this->getCrmProviderId(), self::BUSINESS_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function isStageField(): bool\n {\n return in_array($this->getCrmProviderId(), self::STAGE_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function isPipelineField(): bool\n {\n return in_array($this->getCrmProviderId(), self::PIPELINE_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getCrmConfiguration(): Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function getCrmConfigurationId(): int\n {\n return $this->getAttribute('crm_configuration_id');\n }\n\n /**\n * Currently implemented only for Opportunity fields\n */\n public function isReadOnly(): bool\n {\n // The CRM Field metadata should always be first to be taken into consideration.\n if ($this->getIsReadonly()) {\n return true;\n }\n\n if ($this->getObjectType() !== self::OBJECT_OPPORTUNITY) {\n return false;\n }\n\n if ($this->isPipelineField()) {\n return true;\n }\n\n if ($this->getType() === Field::TYPE_UNSUPPORTED) {\n return true;\n }\n\n if ($this->getCrmConfiguration()->getProviderName() === Configuration::PROVIDER_INTEGRATION_APP) {\n $fieldDefinitions = new CrmFieldDefinitionsManager();\n\n return $fieldDefinitions->isReadOnly($this->getCrmProviderId(), self::OBJECT_OPPORTUNITY);\n }\n\n return false;\n }\n\n public function isPicklist(): bool\n {\n return in_array($this->getType(), [self::TYPE_PICKLIST, self::TYPE_MULTIPICKLIST]);\n }\n\n public function getLength(): ?int\n {\n return $this->getAttribute('length');\n }\n\n public function getDefaultValue(): ?string\n {\n return $this->getAttribute('default_value');\n }\n\n public function setIsReadonly(int $isReadonly): void\n {\n $this->setAttribute('is_readonly', $isReadonly);\n }\n\n public function getIsReadonly(): bool\n {\n return $this->getAttribute('is_readonly') !== FieldReadonlyConstants::FIELD_IS_UPDATABLE;\n }\n\n public function getEntityName(): string\n {\n return ucfirst($this->getObjectType()) . '.' . $this->getCrmProviderId();\n }\n\n public function crmTemplateFields(): HasMany\n {\n return $this->hasMany(CrmTemplateField::class, 'crm_field_id');\n }\n\n public function playbooks(): HasMany\n {\n return $this->hasMany(Playbook::class, 'activity_field_id');\n }\n\n public function getPlaybooks(): Collection\n {\n return $this->getAttribute('playbooks');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"bounds":{"left":0.41289893,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"bounds":{"left":0.42154256,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"bounds":{"left":0.4325133,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"bounds":{"left":0.44115692,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"bounds":{"left":0.44980052,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"bounds":{"left":0.46077126,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"bounds":{"left":0.47174203,"top":0.09896249,"width":0.024268618,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"bounds":{"left":0.49833778,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"bounds":{"left":0.5093085,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7237367,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"21","depth":4,"bounds":{"left":0.6868351,"top":0.123703115,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.6984708,"top":0.123703115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"18","depth":4,"bounds":{"left":0.7077792,"top":0.123703115,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.7194149,"top":0.123703115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"6","depth":4,"bounds":{"left":0.7293883,"top":0.123703115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.7390292,"top":0.12210695,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.7463431,"top":0.12210695,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\n\nselect sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id\nwhere u.team_id = 1;\nSELECT * FROM social_accounts WHERE sociable_id = 1635;\nSELECT * FROM users WHERE id = 1635;\n\nselect * from teams where id = 1;\nselect * from users where team_id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role;\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\nSELECT * FROM automated_reports where id = 71;\nSELECT * FROM automated_report_results where report_id = 71;\nUPDATE automated_reports set playbook_categories = NULL where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT `automated_report_results`.* FROM `automated_report_results`\nINNER JOIN `automated_reports`\n ON `automated_report_results`.`report_id` = `automated_reports`.`id`\nWHERE 1=1\n AND `automated_report_results`.`generated_at` IS NOT NULL\n# AND `automated_report_results`.`sent_at` IS NOT NULL\n AND `automated_reports`.`team_id` = 1\n AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$.\"users\"')\n;\n\nSELECT * FROM automated_reports where id = 67;\nSELECT * FROM automated_reports where id = 42;\nSELECT * FROM users WHERE id = 143; # group 28\n\nselect * from teams where id = 3143;\nselect * from crm_configurations where id = 500;\nselect * from users where name = 'Integration Account'; # 1695\nSELECT * FROM social_accounts WHERE sociable_id = 1695;\n\nselect * from activities where crm_configuration_id = 39\nand recording_state = 'recorded' and duration > 60\nand status = 'completed' and actual_start_time >= '2025-12-01';\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;\n\nselect * from leads;\n\nSELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003\nSELECT * FROM activities WHERE id IN (16,422003);\nSELECT * FROM activities where status = 'failed';\n\nSELECT * FROM tracks WHERE activity_id = 422003;\n\nSELECT\n a.*\nFROM activities a\nJOIN users u ON a.user_id = u.id\nWHERE\n a.status = 'completed'\n AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid\n AND a.deleted_at IS NULL\n AND EXISTS (\n SELECT 1 FROM tracks t\n WHERE t.activity_id = a.id\n AND t.type IN ('audio', 'video')\n )\nORDER BY a.actual_start_time DESC\nLIMIT 25;\n\nselect * from teams where id = 19;\nselect * from crm_configurations where provider = 'pipedrive';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 19 and sa.provider = 'pipedrive';\n\nSELECT * FROM social_accounts WHERE id = 1116;\n\nUPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',\nprovider_refresh_token = '5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc',\nexpires = 1779091997,\nstate = 'connected'\nWHERE id = 1116;\n\n \"provider_user_token\": \"v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA\",\n \"provider_refresh_token\": \"5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc\",\n \"expires\": 1779091997,\n\nselect * from crm_field_values;\n\nselect * from crm_fields where type = 'multi-picklist';\nSELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\nSELECT * FROM crm_fields WHERE id = 3014; # 1885\nSELECT * FROM crm_field_values WHERE crm_field_id = 3014;","depth":4,"on_screen":true,"value":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\n\nselect sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id\nwhere u.team_id = 1;\nSELECT * FROM social_accounts WHERE sociable_id = 1635;\nSELECT * FROM users WHERE id = 1635;\n\nselect * from teams where id = 1;\nselect * from users where team_id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role;\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\nSELECT * FROM automated_reports where id = 71;\nSELECT * FROM automated_report_results where report_id = 71;\nUPDATE automated_reports set playbook_categories = NULL where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT `automated_report_results`.* FROM `automated_report_results`\nINNER JOIN `automated_reports`\n ON `automated_report_results`.`report_id` = `automated_reports`.`id`\nWHERE 1=1\n AND `automated_report_results`.`generated_at` IS NOT NULL\n# AND `automated_report_results`.`sent_at` IS NOT NULL\n AND `automated_reports`.`team_id` = 1\n AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$.\"users\"')\n;\n\nSELECT * FROM automated_reports where id = 67;\nSELECT * FROM automated_reports where id = 42;\nSELECT * FROM users WHERE id = 143; # group 28\n\nselect * from teams where id = 3143;\nselect * from crm_configurations where id = 500;\nselect * from users where name = 'Integration Account'; # 1695\nSELECT * FROM social_accounts WHERE sociable_id = 1695;\n\nselect * from activities where crm_configuration_id = 39\nand recording_state = 'recorded' and duration > 60\nand status = 'completed' and actual_start_time >= '2025-12-01';\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;\n\nselect * from leads;\n\nSELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003\nSELECT * FROM activities WHERE id IN (16,422003);\nSELECT * FROM activities where status = 'failed';\n\nSELECT * FROM tracks WHERE activity_id = 422003;\n\nSELECT\n a.*\nFROM activities a\nJOIN users u ON a.user_id = u.id\nWHERE\n a.status = 'completed'\n AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid\n AND a.deleted_at IS NULL\n AND EXISTS (\n SELECT 1 FROM tracks t\n WHERE t.activity_id = a.id\n AND t.type IN ('audio', 'video')\n )\nORDER BY a.actual_start_time DESC\nLIMIT 25;\n\nselect * from teams where id = 19;\nselect * from crm_configurations where provider = 'pipedrive';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 19 and sa.provider = 'pipedrive';\n\nSELECT * FROM social_accounts WHERE id = 1116;\n\nUPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',\nprovider_refresh_token = '5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc',\nexpires = 1779091997,\nstate = 'connected'\nWHERE id = 1116;\n\n \"provider_user_token\": \"v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA\",\n \"provider_refresh_token\": \"5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc\",\n \"expires\": 1779091997,\n\nselect * from crm_field_values;\n\nselect * from crm_fields where type = 'multi-picklist';\nSELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\nSELECT * FROM crm_fields WHERE id = 3014; # 1885\nSELECT * FROM crm_field_values WHERE crm_field_id = 3014;","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"}]...
|
-1991146549248681854
|
6685203931387336285
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
42
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models\Crm;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Jiminny\Component\Eloquent\Builder;
use Jiminny\Models\Ai\CrmTemplateField;
use Jiminny\Models\Model;
use Jiminny\Models\Playbook;
use Jiminny\Services\Crm\CrmObjects\FieldReadonlyConstants;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
/**
* Jiminny\Models\Crm\Field
*
* @property int $id
* @property mixed|null $uuid
* @property int $crm_configuration_id
* @property string $crm_provider_id
* @property string $label
* @property string|null $description
* @property string $type
* @property int|null $length
* @property string|null $default_value
* @property string $object_type
* @property bool $is_selectable
* @property bool $is_mandatory
* @property bool $is_filterable
* @property bool $is_indexable
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Jiminny\Models\Crm\Configuration $configuration
* @property-read \Jiminny\Models\Crm\Configuration $crm
* @property-read Collection<int, \Jiminny\Models\Crm\FieldData> $data
* @property-read int|null $data_count
* @property-read Collection<int, \Jiminny\Models\Crm\LayoutEntity> $entities
* @property-read int|null $entities_count
* @property-read string $id_string
* @property-read Collection<int, \Jiminny\Models\Crm\FieldValue> $values
* @property-read int|null $values_count
*
* @method static Builder|Field chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\Crm\FieldFactory factory(...$parameters)
* @method static Builder|Field idOrUuId($idOrUuid, bool $first = true)
* @method static Builder|Field indexable()
* @method static Builder|Field newModelQuery()
* @method static Builder|Field newQuery()
* @method static Builder|Field query()
* @method static Builder|Field tasks()
* @method static Builder|Field uuid(string $uuid, bool $first = true)
* @method static Builder|Field whereCreatedAt($value)
* @method static Builder|Field whereCrmConfigurationId($value)
* @method static Builder|Field whereCrmProviderId($value)
* @method static Builder|Field whereDefaultValue($value)
* @method static Builder|Field whereDescription($value)
* @method static Builder|Field whereId($value)
* @method static Builder|Field whereIsFilterable($value)
* @method static Builder|Field whereIsIndexable($value)
* @method static Builder|Field whereIsMandatory($value)
* @method static Builder|Field whereIsSelectable($value)
* @method static Builder|Field whereLabel($value)
* @method static Builder|Field whereLength($value)
* @method static Builder|Field whereObjectType($value)
* @method static Builder|Field whereType($value)
* @method static Builder|Field whereUpdatedAt($value)
* @method static Builder|Field whereUuid($value)
*
* @mixin \Eloquent
*/
class Field extends Model
{
use HasFactory;
use RequiresUUID;
use Enums;
public const int NAME_MAX_LENGTH = 128;
public const int LABEL_MAX_LENGTH = 255;
public const int DESCRIPTION_MAX_LENGTH = 191;
public const string TYPE_MULTIPICKLIST = 'multi-picklist';
// Not yet supported
public const string TYPE_PERCENT = 'percent';
public const string TYPE_PICKLIST = 'picklist';
public const string TYPE_NUMBER = 'number';
public const string TYPE_CURRENCY = 'currency';
public const string TYPE_BOOLEAN = 'boolean';
public const string TYPE_TEXT = 'text';
public const string TYPE_TEXTAREA = 'textarea';
public const string TYPE_EMAIL = 'email';
public const string TYPE_PHONE = 'phone';
public const string TYPE_URL = 'url';
public const string TYPE_DATE = 'date';
public const string TYPE_TIME = 'time';
public const string TYPE_DATETIME = 'datetime';
public const string TYPE_UNSUPPORTED = 'unsupported';
public const string OBJECT_LEAD = 'lead';
public const string OBJECT_ACCOUNT = 'account';
public const string OBJECT_CONTACT = 'contact';
public const string OBJECT_OPPORTUNITY = 'opportunity';
public const string OBJECT_TASK = 'task';
public const string OBJECT_EVENT = 'event';
public const string OBJECT_CALL = 'call';
public const string OBJECT_MEETING = 'meeting';
public const array BUSINESS_TYPE_FIELDS = [
Configuration::PROVIDER_SALESFORCE => 'Type',
Configuration::PROVIDER_HUBSPOT => 'dealtype',
];
public const array PIPELINE_TYPE_FIELDS = [
Configuration::PROVIDER_HUBSPOT => 'pipeline',
];
public const array STAGE_TYPE_FIELDS = [
Configuration::PROVIDER_SALESFORCE => 'StageName',
Configuration::PROVIDER_HUBSPOT => 'dealstage',
Configuration::PROVIDER_CLOSE => 'status_id',
Configuration::PROVIDER_BULLHORN => 'status',
Configuration::PROVIDER_PIPEDRIVE => 'stage_id',
Configuration::PROVIDER_COPPER => 'pipeline_stage_id',
];
public static $enumTypes = [
self::TYPE_PICKLIST,
self::TYPE_NUMBER,
self::TYPE_CURRENCY,
self::TYPE_BOOLEAN,
self::TYPE_TEXT,
self::TYPE_TEXTAREA,
self::TYPE_EMAIL,
self::TYPE_PHONE,
self::TYPE_URL,
self::TYPE_DATE,
self::TYPE_TIME,
self::TYPE_DATETIME,
self::TYPE_UNSUPPORTED,
];
public static $enumObjectTypes = [
self::OBJECT_LEAD,
self::OBJECT_ACCOUNT,
self::OBJECT_CONTACT,
self::OBJECT_OPPORTUNITY,
self::OBJECT_TASK,
self::OBJECT_EVENT,
];
protected $table = 'crm_fields';
protected $fillable = [
'crm_configuration_id',
'crm_provider_id',
'object_type',
'type',
'label',
'description',
'is_selectable',
'is_mandatory',
'length',
'default_value',
'is_indexable',
'is_filterable',
'is_readonly',
];
protected $appends = [
'id_string',
];
protected $hidden = [
'uuid',
'id',
'crm_configuration_id',
];
protected function casts(): array
{
return [
'is_selectable' => 'boolean',
'is_mandatory' => 'boolean',
'is_indexable' => 'boolean',
'is_filterable' => 'boolean',
];
}
public function configuration(): BelongsTo
{
return $this->belongsTo(Configuration::class, 'crm_configuration_id');
}
public function entities(): HasMany
{
return $this->hasMany(LayoutEntity::class, 'crm_field_id');
}
public function getEntities(): Collection
{
/** @var Collection<LayoutEntity> $entities */
$entities = $this->getAttribute('entities');
return $entities;
}
public function values(): HasMany
{
return $this->hasMany(FieldValue::class, 'crm_field_id')->orderBy('sequence');
}
public function getLabel(): string
{
return $this->getAttribute('label');
}
public function getType(): string
{
return $this->getAttribute('type');
}
public function getObjectType(): string
{
/** @var string */
return $this->getAttribute('object_type');
}
public function getCrmProviderId(): string
{
/** @var string */
return $this->getAttribute('crm_provider_id');
}
public function getValues(): Collection
{
return $this->getAttribute('values');
}
public function isIndexable(): bool
{
return $this->getAttribute('is_indexable');
}
public function isFilterable(): bool
{
return $this->getAttribute('is_filterable');
}
public function getId(): int
{
/** @var int */
return $this->getAttribute('id');
}
public function hasDescription(): bool
{
return $this->getAttribute('description') !== null;
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function data()
{
return $this->hasMany(FieldData::class, 'crm_field_id');
}
public function crm(): BelongsTo
{
return $this->belongsTo(Configuration::class, 'crm_configuration_id');
}
#[Scope]
protected function indexable($query)
{
return $query->where('is_indexable', 1);
}
#[Scope]
protected function tasks($query)
{
return $query->where('object_type', self::OBJECT_TASK);
}
public function isBusinessType(): bool
{
return in_array($this->getCrmProviderId(), self::BUSINESS_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function isStageField(): bool
{
return in_array($this->getCrmProviderId(), self::STAGE_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function isPipelineField(): bool
{
return in_array($this->getCrmProviderId(), self::PIPELINE_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function getUuid(): string
{
return $this->getAttribute('id_string');
}
public function getCrmConfiguration(): Configuration
{
return $this->getAttribute('crm');
}
public function getCrmConfigurationId(): int
{
return $this->getAttribute('crm_configuration_id');
}
/**
* Currently implemented only for Opportunity fields
*/
public function isReadOnly(): bool
{
// The CRM Field metadata should always be first to be taken into consideration.
if ($this->getIsReadonly()) {
return true;
}
if ($this->getObjectType() !== self::OBJECT_OPPORTUNITY) {
return false;
}
if ($this->isPipelineField()) {
return true;
}
if ($this->getType() === Field::TYPE_UNSUPPORTED) {
return true;
}
if ($this->getCrmConfiguration()->getProviderName() === Configuration::PROVIDER_INTEGRATION_APP) {
$fieldDefinitions = new CrmFieldDefinitionsManager();
return $fieldDefinitions->isReadOnly($this->getCrmProviderId(), self::OBJECT_OPPORTUNITY);
}
return false;
}
public function isPicklist(): bool
{
return in_array($this->getType(), [self::TYPE_PICKLIST, self::TYPE_MULTIPICKLIST]);
}
public function getLength(): ?int
{
return $this->getAttribute('length');
}
public function getDefaultValue(): ?string
{
return $this->getAttribute('default_value');
}
public function setIsReadonly(int $isReadonly): void
{
$this->setAttribute('is_readonly', $isReadonly);
}
public function getIsReadonly(): bool
{
return $this->getAttribute('is_readonly') !== FieldReadonlyConstants::FIELD_IS_UPDATABLE;
}
public function getEntityName(): string
{
return ucfirst($this->getObjectType()) . '.' . $this->getCrmProviderId();
}
public function crmTemplateFields(): HasMany
{
return $this->hasMany(CrmTemplateField::class, 'crm_field_id');
}
public function playbooks(): HasMany
{
return $this->hasMany(Playbook::class, 'activity_field_id');
}
public function getPlaybooks(): Collection
{
return $this->getAttribute('playbooks');
}
}
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
21
1
18
2
6
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id
where u.team_id = 1;
SELECT * FROM social_accounts WHERE sociable_id = 1635;
SELECT * FROM users WHERE id = 1635;
select * from teams where id = 1;
select * from users where team_id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role;
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
SELECT * FROM automated_reports where id = 71;
SELECT * FROM automated_report_results where report_id = 71;
UPDATE automated_reports set playbook_categories = NULL where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT `automated_report_results`.* FROM `automated_report_results`
INNER JOIN `automated_reports`
ON `automated_report_results`.`report_id` = `automated_reports`.`id`
WHERE 1=1
AND `automated_report_results`.`generated_at` IS NOT NULL
# AND `automated_report_results`.`sent_at` IS NOT NULL
AND `automated_reports`.`team_id` = 1
AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$."users"')
;
SELECT * FROM automated_reports where id = 67;
SELECT * FROM automated_reports where id = 42;
SELECT * FROM users WHERE id = 143; # group 28
select * from teams where id = 3143;
select * from crm_configurations where id = 500;
select * from users where name = 'Integration Account'; # 1695
SELECT * FROM social_accounts WHERE sociable_id = 1695;
select * from activities where crm_configuration_id = 39
and recording_state = 'recorded' and duration > 60
and status = 'completed' and actual_start_time >= '2025-12-01';
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;
select * from leads;
SELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003
SELECT * FROM activities WHERE id IN (16,422003);
SELECT * FROM activities where status = 'failed';
SELECT * FROM tracks WHERE activity_id = 422003;
SELECT
a.*
FROM activities a
JOIN users u ON a.user_id = u.id
WHERE
a.status = 'completed'
AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid
AND a.deleted_at IS NULL
AND EXISTS (
SELECT 1 FROM tracks t
WHERE t.activity_id = a.id
AND t.type IN ('audio', 'video')
)
ORDER BY a.actual_start_time DESC
LIMIT 25;
select * from teams where id = 19;
select * from crm_configurations where provider = 'pipedrive';
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 = 19 and sa.provider = 'pipedrive';
SELECT * FROM social_accounts WHERE id = 1116;
UPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',
provider_refresh_token = '5034113:[TELEGRAM_TOKEN]b2bfc',
expires = 1779091997,
state = 'connected'
WHERE id = 1116;
"provider_user_token": "v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA",
"provider_refresh_token": "5034113:[TELEGRAM_TOKEN]b2bfc",
"expires": 1779091997,
select * from crm_field_values;
select * from crm_fields where type = 'multi-picklist';
SELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
SELECT * FROM crm_fields WHERE id = 3014; # 1885
SELECT * FROM crm_field_values WHERE crm_field_id = 3014;
Project...
|
79489
|
NULL
|
NULL
|
NULL
|
|
79490
|
2786
|
33
|
2026-05-28T06:31:38.235329+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949898235_m1.jpg...
|
PhpStorm
|
faVsco.js – Field.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV (docker)₴2-zshscreenpipe"Fixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated.Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration"is deprecated.Use "@PHP8x0Migration"instead.Rule set "@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-iM.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206masterce9abde868..3800efb7ea JY-20905-tool-search-members-> origin/iorigin/.ad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss*Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-HomeDMsActivityFilesLaterMore+ED→Jiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...° Direct messages&. Petko Kashinskião Stefka Stoyanova:Todor StamatovSteliyan GeorgievVes% MiraP. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y... O::: Appsã Jira CloudToast100% <8•Thu 28 May 9:31:37Describe what you are looking forPetko Kashinski6 0Messagest Add canvas@ FilesLukas Kova'**Tuesday, May 12th ~добро утро+Петко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, но 'MultiPicklist' type, a нe single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастихм, не сьм сигуренще проверяMessage Petko Kashinski+...
|
NULL
|
7964701168804823097
|
NULL
|
click
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV (docker)₴2-zshscreenpipe"Fixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated.Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration"is deprecated.Use "@PHP8x0Migration"instead.Rule set "@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-iM.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206masterce9abde868..3800efb7ea JY-20905-tool-search-members-> origin/iorigin/.ad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss*Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-HomeDMsActivityFilesLaterMore+ED→Jiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...° Direct messages&. Petko Kashinskião Stefka Stoyanova:Todor StamatovSteliyan GeorgievVes% MiraP. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y... O::: Appsã Jira CloudToast100% <8•Thu 28 May 9:31:37Describe what you are looking forPetko Kashinski6 0Messagest Add canvas@ FilesLukas Kova'**Tuesday, May 12th ~добро утро+Петко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, но 'MultiPicklist' type, a нe single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастихм, не сьм сигуренще проверяMessage Petko Kashinski+...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79489
|
2787
|
48
|
2026-05-28T06:31:38.045294+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949898045_m2.jpg...
|
PhpStorm
|
faVsco.js – SF [jiminny@localhost]
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
42
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models\Crm;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Jiminny\Component\Eloquent\Builder;
use Jiminny\Models\Ai\CrmTemplateField;
use Jiminny\Models\Model;
use Jiminny\Models\Playbook;
use Jiminny\Services\Crm\CrmObjects\FieldReadonlyConstants;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
/**
* Jiminny\Models\Crm\Field
*
* @property int $id
* @property mixed|null $uuid
* @property int $crm_configuration_id
* @property string $crm_provider_id
* @property string $label
* @property string|null $description
* @property string $type
* @property int|null $length
* @property string|null $default_value
* @property string $object_type
* @property bool $is_selectable
* @property bool $is_mandatory
* @property bool $is_filterable
* @property bool $is_indexable
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Jiminny\Models\Crm\Configuration $configuration
* @property-read \Jiminny\Models\Crm\Configuration $crm
* @property-read Collection<int, \Jiminny\Models\Crm\FieldData> $data
* @property-read int|null $data_count
* @property-read Collection<int, \Jiminny\Models\Crm\LayoutEntity> $entities
* @property-read int|null $entities_count
* @property-read string $id_string
* @property-read Collection<int, \Jiminny\Models\Crm\FieldValue> $values
* @property-read int|null $values_count
*
* @method static Builder|Field chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\Crm\FieldFactory factory(...$parameters)
* @method static Builder|Field idOrUuId($idOrUuid, bool $first = true)
* @method static Builder|Field indexable()
* @method static Builder|Field newModelQuery()
* @method static Builder|Field newQuery()
* @method static Builder|Field query()
* @method static Builder|Field tasks()
* @method static Builder|Field uuid(string $uuid, bool $first = true)
* @method static Builder|Field whereCreatedAt($value)
* @method static Builder|Field whereCrmConfigurationId($value)
* @method static Builder|Field whereCrmProviderId($value)
* @method static Builder|Field whereDefaultValue($value)
* @method static Builder|Field whereDescription($value)
* @method static Builder|Field whereId($value)
* @method static Builder|Field whereIsFilterable($value)
* @method static Builder|Field whereIsIndexable($value)
* @method static Builder|Field whereIsMandatory($value)
* @method static Builder|Field whereIsSelectable($value)
* @method static Builder|Field whereLabel($value)
* @method static Builder|Field whereLength($value)
* @method static Builder|Field whereObjectType($value)
* @method static Builder|Field whereType($value)
* @method static Builder|Field whereUpdatedAt($value)
* @method static Builder|Field whereUuid($value)
*
* @mixin \Eloquent
*/
class Field extends Model
{
use HasFactory;
use RequiresUUID;
use Enums;
public const int NAME_MAX_LENGTH = 128;
public const int LABEL_MAX_LENGTH = 255;
public const int DESCRIPTION_MAX_LENGTH = 191;
public const string TYPE_MULTIPICKLIST = 'multi-picklist';
// Not yet supported
public const string TYPE_PERCENT = 'percent';
public const string TYPE_PICKLIST = 'picklist';
public const string TYPE_NUMBER = 'number';
public const string TYPE_CURRENCY = 'currency';
public const string TYPE_BOOLEAN = 'boolean';
public const string TYPE_TEXT = 'text';
public const string TYPE_TEXTAREA = 'textarea';
public const string TYPE_EMAIL = 'email';
public const string TYPE_PHONE = 'phone';
public const string TYPE_URL = 'url';
public const string TYPE_DATE = 'date';
public const string TYPE_TIME = 'time';
public const string TYPE_DATETIME = 'datetime';
public const string TYPE_UNSUPPORTED = 'unsupported';
public const string OBJECT_LEAD = 'lead';
public const string OBJECT_ACCOUNT = 'account';
public const string OBJECT_CONTACT = 'contact';
public const string OBJECT_OPPORTUNITY = 'opportunity';
public const string OBJECT_TASK = 'task';
public const string OBJECT_EVENT = 'event';
public const string OBJECT_CALL = 'call';
public const string OBJECT_MEETING = 'meeting';
public const array BUSINESS_TYPE_FIELDS = [
Configuration::PROVIDER_SALESFORCE => 'Type',
Configuration::PROVIDER_HUBSPOT => 'dealtype',
];
public const array PIPELINE_TYPE_FIELDS = [
Configuration::PROVIDER_HUBSPOT => 'pipeline',
];
public const array STAGE_TYPE_FIELDS = [
Configuration::PROVIDER_SALESFORCE => 'StageName',
Configuration::PROVIDER_HUBSPOT => 'dealstage',
Configuration::PROVIDER_CLOSE => 'status_id',
Configuration::PROVIDER_BULLHORN => 'status',
Configuration::PROVIDER_PIPEDRIVE => 'stage_id',
Configuration::PROVIDER_COPPER => 'pipeline_stage_id',
];
public static $enumTypes = [
self::TYPE_PICKLIST,
self::TYPE_NUMBER,
self::TYPE_CURRENCY,
self::TYPE_BOOLEAN,
self::TYPE_TEXT,
self::TYPE_TEXTAREA,
self::TYPE_EMAIL,
self::TYPE_PHONE,
self::TYPE_URL,
self::TYPE_DATE,
self::TYPE_TIME,
self::TYPE_DATETIME,
self::TYPE_UNSUPPORTED,
];
public static $enumObjectTypes = [
self::OBJECT_LEAD,
self::OBJECT_ACCOUNT,
self::OBJECT_CONTACT,
self::OBJECT_OPPORTUNITY,
self::OBJECT_TASK,
self::OBJECT_EVENT,
];
protected $table = 'crm_fields';
protected $fillable = [
'crm_configuration_id',
'crm_provider_id',
'object_type',
'type',
'label',
'description',
'is_selectable',
'is_mandatory',
'length',
'default_value',
'is_indexable',
'is_filterable',
'is_readonly',
];
protected $appends = [
'id_string',
];
protected $hidden = [
'uuid',
'id',
'crm_configuration_id',
];
protected function casts(): array
{
return [
'is_selectable' => 'boolean',
'is_mandatory' => 'boolean',
'is_indexable' => 'boolean',
'is_filterable' => 'boolean',
];
}
public function configuration(): BelongsTo
{
return $this->belongsTo(Configuration::class, 'crm_configuration_id');
}
public function entities(): HasMany
{
return $this->hasMany(LayoutEntity::class, 'crm_field_id');
}
public function getEntities(): Collection
{
/** @var Collection<LayoutEntity> $entities */
$entities = $this->getAttribute('entities');
return $entities;
}
public function values(): HasMany
{
return $this->hasMany(FieldValue::class, 'crm_field_id')->orderBy('sequence');
}
public function getLabel(): string
{
return $this->getAttribute('label');
}
public function getType(): string
{
return $this->getAttribute('type');
}
public function getObjectType(): string
{
/** @var string */
return $this->getAttribute('object_type');
}
public function getCrmProviderId(): string
{
/** @var string */
return $this->getAttribute('crm_provider_id');
}
public function getValues(): Collection
{
return $this->getAttribute('values');
}
public function isIndexable(): bool
{
return $this->getAttribute('is_indexable');
}
public function isFilterable(): bool
{
return $this->getAttribute('is_filterable');
}
public function getId(): int
{
/** @var int */
return $this->getAttribute('id');
}
public function hasDescription(): bool
{
return $this->getAttribute('description') !== null;
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function data()
{
return $this->hasMany(FieldData::class, 'crm_field_id');
}
public function crm(): BelongsTo
{
return $this->belongsTo(Configuration::class, 'crm_configuration_id');
}
#[Scope]
protected function indexable($query)
{
return $query->where('is_indexable', 1);
}
#[Scope]
protected function tasks($query)
{
return $query->where('object_type', self::OBJECT_TASK);
}
public function isBusinessType(): bool
{
return in_array($this->getCrmProviderId(), self::BUSINESS_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function isStageField(): bool
{
return in_array($this->getCrmProviderId(), self::STAGE_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function isPipelineField(): bool
{
return in_array($this->getCrmProviderId(), self::PIPELINE_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function getUuid(): string
{
return $this->getAttribute('id_string');
}
public function getCrmConfiguration(): Configuration
{
return $this->getAttribute('crm');
}
public function getCrmConfigurationId(): int
{
return $this->getAttribute('crm_configuration_id');
}
/**
* Currently implemented only for Opportunity fields
*/
public function isReadOnly(): bool
{
// The CRM Field metadata should always be first to be taken into consideration.
if ($this->getIsReadonly()) {
return true;
}
if ($this->getObjectType() !== self::OBJECT_OPPORTUNITY) {
return false;
}
if ($this->isPipelineField()) {
return true;
}
if ($this->getType() === Field::TYPE_UNSUPPORTED) {
return true;
}
if ($this->getCrmConfiguration()->getProviderName() === Configuration::PROVIDER_INTEGRATION_APP) {
$fieldDefinitions = new CrmFieldDefinitionsManager();
return $fieldDefinitions->isReadOnly($this->getCrmProviderId(), self::OBJECT_OPPORTUNITY);
}
return false;
}
public function isPicklist(): bool
{
return in_array($this->getType(), [self::TYPE_PICKLIST, self::TYPE_MULTIPICKLIST]);
}
public function getLength(): ?int
{
return $this->getAttribute('length');
}
public function getDefaultValue(): ?string
{
return $this->getAttribute('default_value');
}
public function setIsReadonly(int $isReadonly): void
{
$this->setAttribute('is_readonly', $isReadonly);
}
public function getIsReadonly(): bool
{
return $this->getAttribute('is_readonly') !== FieldReadonlyConstants::FIELD_IS_UPDATABLE;
}
public function getEntityName(): string
{
return ucfirst($this->getObjectType()) . '.' . $this->getCrmProviderId();
}
public function crmTemplateFields(): HasMany
{
return $this->hasMany(CrmTemplateField::class, 'crm_field_id');
}
public function playbooks(): HasMany
{
return $this->hasMany(Playbook::class, 'activity_field_id');
}
public function getPlaybooks(): Collection
{
return $this->getAttribute('playbooks');
}
}
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
21
1
18
2
6
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id
where u.team_id = 1;
SELECT * FROM social_accounts WHERE sociable_id = 1635;
SELECT * FROM users WHERE id = 1635;
select * from teams where id = 1;
select * from users where team_id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role;
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
SELECT * FROM automated_reports where id = 71;
SELECT * FROM automated_report_results where report_id = 71;
UPDATE automated_reports set playbook_categories = NULL where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT `automated_report_results`.* FROM `automated_report_results`
INNER JOIN `automated_reports`
ON `automated_report_results`.`report_id` = `automated_reports`.`id`
WHERE 1=1
AND `automated_report_results`.`generated_at` IS NOT NULL
# AND `automated_report_results`.`sent_at` IS NOT NULL
AND `automated_reports`.`team_id` = 1
AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$."users"')
;
SELECT * FROM automated_reports where id = 67;
SELECT * FROM automated_reports where id = 42;
SELECT * FROM users WHERE id = 143; # group 28
select * from teams where id = 3143;
select * from crm_configurations where id = 500;
select * from users where name = 'Integration Account'; # 1695
SELECT * FROM social_accounts WHERE sociable_id = 1695;
select * from activities where crm_configuration_id = 39
and recording_state = 'recorded' and duration > 60
and status = 'completed' and actual_start_time >= '2025-12-01';
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;
select * from leads;
SELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003
SELECT * FROM activities WHERE id IN (16,422003);
SELECT * FROM activities where status = 'failed';
SELECT * FROM tracks WHERE activity_id = 422003;
SELECT
a.*
FROM activities a
JOIN users u ON a.user_id = u.id
WHERE
a.status = 'completed'
AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid
AND a.deleted_at IS NULL
AND EXISTS (
SELECT 1 FROM tracks t
WHERE t.activity_id = a.id
AND t.type IN ('audio', 'video')
)
ORDER BY a.actual_start_time DESC
LIMIT 25;
select * from teams where id = 19;
select * from crm_configurations where provider = 'pipedrive';
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 = 19 and sa.provider = 'pipedrive';
SELECT * FROM social_accounts WHERE id = 1116;
UPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',
provider_refresh_token = '5034113:[TELEGRAM_TOKEN]b2bfc',
expires = 1779091997,
state = 'connected'
WHERE id = 1116;
"provider_user_token": "v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA",
"provider_refresh_token": "5034113:[TELEGRAM_TOKEN]b2bfc",
"expires": 1779091997,
select * from crm_field_values;
select * from crm_fields where type = 'multi-picklist';
SELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
SELECT * FROM crm_fields WHERE id = 3014; # 1885
SELECT * FROM crm_field_values WHERE crm_field_id = 3014;
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-20915-fix-missing-header-text-relay, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09740692,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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.8374335,"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":"TextRelayServiceTest","depth":6,"bounds":{"left":0.85272604,"top":0.019952115,"width":0.062832445,"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 'TextRelayServiceTest'","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 'TextRelayServiceTest'","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":"42","depth":4,"bounds":{"left":0.375,"top":0.10055866,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.38730052,"top":0.10055866,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39694148,"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.40425533,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Models\\Crm;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Jiminny\\Component\\Eloquent\\Builder;\nuse Jiminny\\Models\\Ai\\CrmTemplateField;\nuse Jiminny\\Models\\Model;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Services\\Crm\\CrmObjects\\FieldReadonlyConstants;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\n\n/**\n * Jiminny\\Models\\Crm\\Field\n *\n * @property int $id\n * @property mixed|null $uuid\n * @property int $crm_configuration_id\n * @property string $crm_provider_id\n * @property string $label\n * @property string|null $description\n * @property string $type\n * @property int|null $length\n * @property string|null $default_value\n * @property string $object_type\n * @property bool $is_selectable\n * @property bool $is_mandatory\n * @property bool $is_filterable\n * @property bool $is_indexable\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property-read \\Jiminny\\Models\\Crm\\Configuration $configuration\n * @property-read \\Jiminny\\Models\\Crm\\Configuration $crm\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\FieldData> $data\n * @property-read int|null $data_count\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\LayoutEntity> $entities\n * @property-read int|null $entities_count\n * @property-read string $id_string\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\FieldValue> $values\n * @property-read int|null $values_count\n *\n * @method static Builder|Field chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\Crm\\FieldFactory factory(...$parameters)\n * @method static Builder|Field idOrUuId($idOrUuid, bool $first = true)\n * @method static Builder|Field indexable()\n * @method static Builder|Field newModelQuery()\n * @method static Builder|Field newQuery()\n * @method static Builder|Field query()\n * @method static Builder|Field tasks()\n * @method static Builder|Field uuid(string $uuid, bool $first = true)\n * @method static Builder|Field whereCreatedAt($value)\n * @method static Builder|Field whereCrmConfigurationId($value)\n * @method static Builder|Field whereCrmProviderId($value)\n * @method static Builder|Field whereDefaultValue($value)\n * @method static Builder|Field whereDescription($value)\n * @method static Builder|Field whereId($value)\n * @method static Builder|Field whereIsFilterable($value)\n * @method static Builder|Field whereIsIndexable($value)\n * @method static Builder|Field whereIsMandatory($value)\n * @method static Builder|Field whereIsSelectable($value)\n * @method static Builder|Field whereLabel($value)\n * @method static Builder|Field whereLength($value)\n * @method static Builder|Field whereObjectType($value)\n * @method static Builder|Field whereType($value)\n * @method static Builder|Field whereUpdatedAt($value)\n * @method static Builder|Field whereUuid($value)\n *\n * @mixin \\Eloquent\n */\nclass Field extends Model\n{\n use HasFactory;\n\n use RequiresUUID;\n use Enums;\n\n public const int NAME_MAX_LENGTH = 128;\n public const int LABEL_MAX_LENGTH = 255;\n public const int DESCRIPTION_MAX_LENGTH = 191;\n\n public const string TYPE_MULTIPICKLIST = 'multi-picklist';\n // Not yet supported\n public const string TYPE_PERCENT = 'percent';\n\n public const string TYPE_PICKLIST = 'picklist';\n public const string TYPE_NUMBER = 'number';\n public const string TYPE_CURRENCY = 'currency';\n public const string TYPE_BOOLEAN = 'boolean';\n public const string TYPE_TEXT = 'text';\n public const string TYPE_TEXTAREA = 'textarea';\n public const string TYPE_EMAIL = 'email';\n public const string TYPE_PHONE = 'phone';\n public const string TYPE_URL = 'url';\n public const string TYPE_DATE = 'date';\n public const string TYPE_TIME = 'time';\n public const string TYPE_DATETIME = 'datetime';\n public const string TYPE_UNSUPPORTED = 'unsupported';\n\n public const string OBJECT_LEAD = 'lead';\n public const string OBJECT_ACCOUNT = 'account';\n public const string OBJECT_CONTACT = 'contact';\n public const string OBJECT_OPPORTUNITY = 'opportunity';\n public const string OBJECT_TASK = 'task';\n public const string OBJECT_EVENT = 'event';\n public const string OBJECT_CALL = 'call';\n public const string OBJECT_MEETING = 'meeting';\n\n public const array BUSINESS_TYPE_FIELDS = [\n Configuration::PROVIDER_SALESFORCE => 'Type',\n Configuration::PROVIDER_HUBSPOT => 'dealtype',\n ];\n\n public const array PIPELINE_TYPE_FIELDS = [\n Configuration::PROVIDER_HUBSPOT => 'pipeline',\n ];\n\n public const array STAGE_TYPE_FIELDS = [\n Configuration::PROVIDER_SALESFORCE => 'StageName',\n Configuration::PROVIDER_HUBSPOT => 'dealstage',\n Configuration::PROVIDER_CLOSE => 'status_id',\n Configuration::PROVIDER_BULLHORN => 'status',\n Configuration::PROVIDER_PIPEDRIVE => 'stage_id',\n Configuration::PROVIDER_COPPER => 'pipeline_stage_id',\n ];\n\n public static $enumTypes = [\n self::TYPE_PICKLIST,\n self::TYPE_NUMBER,\n self::TYPE_CURRENCY,\n self::TYPE_BOOLEAN,\n self::TYPE_TEXT,\n self::TYPE_TEXTAREA,\n self::TYPE_EMAIL,\n self::TYPE_PHONE,\n self::TYPE_URL,\n self::TYPE_DATE,\n self::TYPE_TIME,\n self::TYPE_DATETIME,\n self::TYPE_UNSUPPORTED,\n ];\n\n public static $enumObjectTypes = [\n self::OBJECT_LEAD,\n self::OBJECT_ACCOUNT,\n self::OBJECT_CONTACT,\n self::OBJECT_OPPORTUNITY,\n self::OBJECT_TASK,\n self::OBJECT_EVENT,\n ];\n\n protected $table = 'crm_fields';\n\n protected $fillable = [\n 'crm_configuration_id',\n 'crm_provider_id',\n 'object_type',\n 'type',\n 'label',\n 'description',\n 'is_selectable',\n 'is_mandatory',\n 'length',\n 'default_value',\n 'is_indexable',\n 'is_filterable',\n 'is_readonly',\n ];\n\n protected $appends = [\n 'id_string',\n ];\n\n protected $hidden = [\n 'uuid',\n 'id',\n 'crm_configuration_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'is_selectable' => 'boolean',\n 'is_mandatory' => 'boolean',\n 'is_indexable' => 'boolean',\n 'is_filterable' => 'boolean',\n ];\n }\n\n public function configuration(): BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function entities(): HasMany\n {\n return $this->hasMany(LayoutEntity::class, 'crm_field_id');\n }\n\n public function getEntities(): Collection\n {\n /** @var Collection<LayoutEntity> $entities */\n $entities = $this->getAttribute('entities');\n\n return $entities;\n }\n\n public function values(): HasMany\n {\n return $this->hasMany(FieldValue::class, 'crm_field_id')->orderBy('sequence');\n }\n\n public function getLabel(): string\n {\n return $this->getAttribute('label');\n }\n\n public function getType(): string\n {\n return $this->getAttribute('type');\n }\n\n public function getObjectType(): string\n {\n /** @var string */\n return $this->getAttribute('object_type');\n }\n\n public function getCrmProviderId(): string\n {\n /** @var string */\n return $this->getAttribute('crm_provider_id');\n }\n\n public function getValues(): Collection\n {\n return $this->getAttribute('values');\n }\n\n public function isIndexable(): bool\n {\n return $this->getAttribute('is_indexable');\n }\n\n public function isFilterable(): bool\n {\n return $this->getAttribute('is_filterable');\n }\n\n public function getId(): int\n {\n /** @var int */\n return $this->getAttribute('id');\n }\n\n public function hasDescription(): bool\n {\n return $this->getAttribute('description') !== null;\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function data()\n {\n return $this->hasMany(FieldData::class, 'crm_field_id');\n }\n\n public function crm(): BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n #[Scope]\n protected function indexable($query)\n {\n return $query->where('is_indexable', 1);\n }\n\n #[Scope]\n protected function tasks($query)\n {\n return $query->where('object_type', self::OBJECT_TASK);\n }\n\n public function isBusinessType(): bool\n {\n return in_array($this->getCrmProviderId(), self::BUSINESS_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function isStageField(): bool\n {\n return in_array($this->getCrmProviderId(), self::STAGE_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function isPipelineField(): bool\n {\n return in_array($this->getCrmProviderId(), self::PIPELINE_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getCrmConfiguration(): Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function getCrmConfigurationId(): int\n {\n return $this->getAttribute('crm_configuration_id');\n }\n\n /**\n * Currently implemented only for Opportunity fields\n */\n public function isReadOnly(): bool\n {\n // The CRM Field metadata should always be first to be taken into consideration.\n if ($this->getIsReadonly()) {\n return true;\n }\n\n if ($this->getObjectType() !== self::OBJECT_OPPORTUNITY) {\n return false;\n }\n\n if ($this->isPipelineField()) {\n return true;\n }\n\n if ($this->getType() === Field::TYPE_UNSUPPORTED) {\n return true;\n }\n\n if ($this->getCrmConfiguration()->getProviderName() === Configuration::PROVIDER_INTEGRATION_APP) {\n $fieldDefinitions = new CrmFieldDefinitionsManager();\n\n return $fieldDefinitions->isReadOnly($this->getCrmProviderId(), self::OBJECT_OPPORTUNITY);\n }\n\n return false;\n }\n\n public function isPicklist(): bool\n {\n return in_array($this->getType(), [self::TYPE_PICKLIST, self::TYPE_MULTIPICKLIST]);\n }\n\n public function getLength(): ?int\n {\n return $this->getAttribute('length');\n }\n\n public function getDefaultValue(): ?string\n {\n return $this->getAttribute('default_value');\n }\n\n public function setIsReadonly(int $isReadonly): void\n {\n $this->setAttribute('is_readonly', $isReadonly);\n }\n\n public function getIsReadonly(): bool\n {\n return $this->getAttribute('is_readonly') !== FieldReadonlyConstants::FIELD_IS_UPDATABLE;\n }\n\n public function getEntityName(): string\n {\n return ucfirst($this->getObjectType()) . '.' . $this->getCrmProviderId();\n }\n\n public function crmTemplateFields(): HasMany\n {\n return $this->hasMany(CrmTemplateField::class, 'crm_field_id');\n }\n\n public function playbooks(): HasMany\n {\n return $this->hasMany(Playbook::class, 'activity_field_id');\n }\n\n public function getPlaybooks(): Collection\n {\n return $this->getAttribute('playbooks');\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Models\\Crm;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Jiminny\\Component\\Eloquent\\Builder;\nuse Jiminny\\Models\\Ai\\CrmTemplateField;\nuse Jiminny\\Models\\Model;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Services\\Crm\\CrmObjects\\FieldReadonlyConstants;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\n\n/**\n * Jiminny\\Models\\Crm\\Field\n *\n * @property int $id\n * @property mixed|null $uuid\n * @property int $crm_configuration_id\n * @property string $crm_provider_id\n * @property string $label\n * @property string|null $description\n * @property string $type\n * @property int|null $length\n * @property string|null $default_value\n * @property string $object_type\n * @property bool $is_selectable\n * @property bool $is_mandatory\n * @property bool $is_filterable\n * @property bool $is_indexable\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property-read \\Jiminny\\Models\\Crm\\Configuration $configuration\n * @property-read \\Jiminny\\Models\\Crm\\Configuration $crm\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\FieldData> $data\n * @property-read int|null $data_count\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\LayoutEntity> $entities\n * @property-read int|null $entities_count\n * @property-read string $id_string\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\FieldValue> $values\n * @property-read int|null $values_count\n *\n * @method static Builder|Field chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\Crm\\FieldFactory factory(...$parameters)\n * @method static Builder|Field idOrUuId($idOrUuid, bool $first = true)\n * @method static Builder|Field indexable()\n * @method static Builder|Field newModelQuery()\n * @method static Builder|Field newQuery()\n * @method static Builder|Field query()\n * @method static Builder|Field tasks()\n * @method static Builder|Field uuid(string $uuid, bool $first = true)\n * @method static Builder|Field whereCreatedAt($value)\n * @method static Builder|Field whereCrmConfigurationId($value)\n * @method static Builder|Field whereCrmProviderId($value)\n * @method static Builder|Field whereDefaultValue($value)\n * @method static Builder|Field whereDescription($value)\n * @method static Builder|Field whereId($value)\n * @method static Builder|Field whereIsFilterable($value)\n * @method static Builder|Field whereIsIndexable($value)\n * @method static Builder|Field whereIsMandatory($value)\n * @method static Builder|Field whereIsSelectable($value)\n * @method static Builder|Field whereLabel($value)\n * @method static Builder|Field whereLength($value)\n * @method static Builder|Field whereObjectType($value)\n * @method static Builder|Field whereType($value)\n * @method static Builder|Field whereUpdatedAt($value)\n * @method static Builder|Field whereUuid($value)\n *\n * @mixin \\Eloquent\n */\nclass Field extends Model\n{\n use HasFactory;\n\n use RequiresUUID;\n use Enums;\n\n public const int NAME_MAX_LENGTH = 128;\n public const int LABEL_MAX_LENGTH = 255;\n public const int DESCRIPTION_MAX_LENGTH = 191;\n\n public const string TYPE_MULTIPICKLIST = 'multi-picklist';\n // Not yet supported\n public const string TYPE_PERCENT = 'percent';\n\n public const string TYPE_PICKLIST = 'picklist';\n public const string TYPE_NUMBER = 'number';\n public const string TYPE_CURRENCY = 'currency';\n public const string TYPE_BOOLEAN = 'boolean';\n public const string TYPE_TEXT = 'text';\n public const string TYPE_TEXTAREA = 'textarea';\n public const string TYPE_EMAIL = 'email';\n public const string TYPE_PHONE = 'phone';\n public const string TYPE_URL = 'url';\n public const string TYPE_DATE = 'date';\n public const string TYPE_TIME = 'time';\n public const string TYPE_DATETIME = 'datetime';\n public const string TYPE_UNSUPPORTED = 'unsupported';\n\n public const string OBJECT_LEAD = 'lead';\n public const string OBJECT_ACCOUNT = 'account';\n public const string OBJECT_CONTACT = 'contact';\n public const string OBJECT_OPPORTUNITY = 'opportunity';\n public const string OBJECT_TASK = 'task';\n public const string OBJECT_EVENT = 'event';\n public const string OBJECT_CALL = 'call';\n public const string OBJECT_MEETING = 'meeting';\n\n public const array BUSINESS_TYPE_FIELDS = [\n Configuration::PROVIDER_SALESFORCE => 'Type',\n Configuration::PROVIDER_HUBSPOT => 'dealtype',\n ];\n\n public const array PIPELINE_TYPE_FIELDS = [\n Configuration::PROVIDER_HUBSPOT => 'pipeline',\n ];\n\n public const array STAGE_TYPE_FIELDS = [\n Configuration::PROVIDER_SALESFORCE => 'StageName',\n Configuration::PROVIDER_HUBSPOT => 'dealstage',\n Configuration::PROVIDER_CLOSE => 'status_id',\n Configuration::PROVIDER_BULLHORN => 'status',\n Configuration::PROVIDER_PIPEDRIVE => 'stage_id',\n Configuration::PROVIDER_COPPER => 'pipeline_stage_id',\n ];\n\n public static $enumTypes = [\n self::TYPE_PICKLIST,\n self::TYPE_NUMBER,\n self::TYPE_CURRENCY,\n self::TYPE_BOOLEAN,\n self::TYPE_TEXT,\n self::TYPE_TEXTAREA,\n self::TYPE_EMAIL,\n self::TYPE_PHONE,\n self::TYPE_URL,\n self::TYPE_DATE,\n self::TYPE_TIME,\n self::TYPE_DATETIME,\n self::TYPE_UNSUPPORTED,\n ];\n\n public static $enumObjectTypes = [\n self::OBJECT_LEAD,\n self::OBJECT_ACCOUNT,\n self::OBJECT_CONTACT,\n self::OBJECT_OPPORTUNITY,\n self::OBJECT_TASK,\n self::OBJECT_EVENT,\n ];\n\n protected $table = 'crm_fields';\n\n protected $fillable = [\n 'crm_configuration_id',\n 'crm_provider_id',\n 'object_type',\n 'type',\n 'label',\n 'description',\n 'is_selectable',\n 'is_mandatory',\n 'length',\n 'default_value',\n 'is_indexable',\n 'is_filterable',\n 'is_readonly',\n ];\n\n protected $appends = [\n 'id_string',\n ];\n\n protected $hidden = [\n 'uuid',\n 'id',\n 'crm_configuration_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'is_selectable' => 'boolean',\n 'is_mandatory' => 'boolean',\n 'is_indexable' => 'boolean',\n 'is_filterable' => 'boolean',\n ];\n }\n\n public function configuration(): BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function entities(): HasMany\n {\n return $this->hasMany(LayoutEntity::class, 'crm_field_id');\n }\n\n public function getEntities(): Collection\n {\n /** @var Collection<LayoutEntity> $entities */\n $entities = $this->getAttribute('entities');\n\n return $entities;\n }\n\n public function values(): HasMany\n {\n return $this->hasMany(FieldValue::class, 'crm_field_id')->orderBy('sequence');\n }\n\n public function getLabel(): string\n {\n return $this->getAttribute('label');\n }\n\n public function getType(): string\n {\n return $this->getAttribute('type');\n }\n\n public function getObjectType(): string\n {\n /** @var string */\n return $this->getAttribute('object_type');\n }\n\n public function getCrmProviderId(): string\n {\n /** @var string */\n return $this->getAttribute('crm_provider_id');\n }\n\n public function getValues(): Collection\n {\n return $this->getAttribute('values');\n }\n\n public function isIndexable(): bool\n {\n return $this->getAttribute('is_indexable');\n }\n\n public function isFilterable(): bool\n {\n return $this->getAttribute('is_filterable');\n }\n\n public function getId(): int\n {\n /** @var int */\n return $this->getAttribute('id');\n }\n\n public function hasDescription(): bool\n {\n return $this->getAttribute('description') !== null;\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function data()\n {\n return $this->hasMany(FieldData::class, 'crm_field_id');\n }\n\n public function crm(): BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n #[Scope]\n protected function indexable($query)\n {\n return $query->where('is_indexable', 1);\n }\n\n #[Scope]\n protected function tasks($query)\n {\n return $query->where('object_type', self::OBJECT_TASK);\n }\n\n public function isBusinessType(): bool\n {\n return in_array($this->getCrmProviderId(), self::BUSINESS_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function isStageField(): bool\n {\n return in_array($this->getCrmProviderId(), self::STAGE_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function isPipelineField(): bool\n {\n return in_array($this->getCrmProviderId(), self::PIPELINE_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getCrmConfiguration(): Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function getCrmConfigurationId(): int\n {\n return $this->getAttribute('crm_configuration_id');\n }\n\n /**\n * Currently implemented only for Opportunity fields\n */\n public function isReadOnly(): bool\n {\n // The CRM Field metadata should always be first to be taken into consideration.\n if ($this->getIsReadonly()) {\n return true;\n }\n\n if ($this->getObjectType() !== self::OBJECT_OPPORTUNITY) {\n return false;\n }\n\n if ($this->isPipelineField()) {\n return true;\n }\n\n if ($this->getType() === Field::TYPE_UNSUPPORTED) {\n return true;\n }\n\n if ($this->getCrmConfiguration()->getProviderName() === Configuration::PROVIDER_INTEGRATION_APP) {\n $fieldDefinitions = new CrmFieldDefinitionsManager();\n\n return $fieldDefinitions->isReadOnly($this->getCrmProviderId(), self::OBJECT_OPPORTUNITY);\n }\n\n return false;\n }\n\n public function isPicklist(): bool\n {\n return in_array($this->getType(), [self::TYPE_PICKLIST, self::TYPE_MULTIPICKLIST]);\n }\n\n public function getLength(): ?int\n {\n return $this->getAttribute('length');\n }\n\n public function getDefaultValue(): ?string\n {\n return $this->getAttribute('default_value');\n }\n\n public function setIsReadonly(int $isReadonly): void\n {\n $this->setAttribute('is_readonly', $isReadonly);\n }\n\n public function getIsReadonly(): bool\n {\n return $this->getAttribute('is_readonly') !== FieldReadonlyConstants::FIELD_IS_UPDATABLE;\n }\n\n public function getEntityName(): string\n {\n return ucfirst($this->getObjectType()) . '.' . $this->getCrmProviderId();\n }\n\n public function crmTemplateFields(): HasMany\n {\n return $this->hasMany(CrmTemplateField::class, 'crm_field_id');\n }\n\n public function playbooks(): HasMany\n {\n return $this->hasMany(Playbook::class, 'activity_field_id');\n }\n\n public function getPlaybooks(): Collection\n {\n return $this->getAttribute('playbooks');\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.41289893,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"bounds":{"left":0.42154256,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"bounds":{"left":0.4325133,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"bounds":{"left":0.44115692,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"bounds":{"left":0.44980052,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"bounds":{"left":0.46077126,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"bounds":{"left":0.47174203,"top":0.09896249,"width":0.024268618,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"bounds":{"left":0.49833778,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"bounds":{"left":0.5093085,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7237367,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"21","depth":4,"bounds":{"left":0.6868351,"top":0.123703115,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.6984708,"top":0.123703115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"18","depth":4,"bounds":{"left":0.7077792,"top":0.123703115,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.7194149,"top":0.123703115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"6","depth":4,"bounds":{"left":0.7293883,"top":0.123703115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.7390292,"top":0.12210695,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.7463431,"top":0.12210695,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\n\nselect sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id\nwhere u.team_id = 1;\nSELECT * FROM social_accounts WHERE sociable_id = 1635;\nSELECT * FROM users WHERE id = 1635;\n\nselect * from teams where id = 1;\nselect * from users where team_id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role;\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\nSELECT * FROM automated_reports where id = 71;\nSELECT * FROM automated_report_results where report_id = 71;\nUPDATE automated_reports set playbook_categories = NULL where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT `automated_report_results`.* FROM `automated_report_results`\nINNER JOIN `automated_reports`\n ON `automated_report_results`.`report_id` = `automated_reports`.`id`\nWHERE 1=1\n AND `automated_report_results`.`generated_at` IS NOT NULL\n# AND `automated_report_results`.`sent_at` IS NOT NULL\n AND `automated_reports`.`team_id` = 1\n AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$.\"users\"')\n;\n\nSELECT * FROM automated_reports where id = 67;\nSELECT * FROM automated_reports where id = 42;\nSELECT * FROM users WHERE id = 143; # group 28\n\nselect * from teams where id = 3143;\nselect * from crm_configurations where id = 500;\nselect * from users where name = 'Integration Account'; # 1695\nSELECT * FROM social_accounts WHERE sociable_id = 1695;\n\nselect * from activities where crm_configuration_id = 39\nand recording_state = 'recorded' and duration > 60\nand status = 'completed' and actual_start_time >= '2025-12-01';\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;\n\nselect * from leads;\n\nSELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003\nSELECT * FROM activities WHERE id IN (16,422003);\nSELECT * FROM activities where status = 'failed';\n\nSELECT * FROM tracks WHERE activity_id = 422003;\n\nSELECT\n a.*\nFROM activities a\nJOIN users u ON a.user_id = u.id\nWHERE\n a.status = 'completed'\n AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid\n AND a.deleted_at IS NULL\n AND EXISTS (\n SELECT 1 FROM tracks t\n WHERE t.activity_id = a.id\n AND t.type IN ('audio', 'video')\n )\nORDER BY a.actual_start_time DESC\nLIMIT 25;\n\nselect * from teams where id = 19;\nselect * from crm_configurations where provider = 'pipedrive';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 19 and sa.provider = 'pipedrive';\n\nSELECT * FROM social_accounts WHERE id = 1116;\n\nUPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',\nprovider_refresh_token = '5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc',\nexpires = 1779091997,\nstate = 'connected'\nWHERE id = 1116;\n\n \"provider_user_token\": \"v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA\",\n \"provider_refresh_token\": \"5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc\",\n \"expires\": 1779091997,\n\nselect * from crm_field_values;\n\nselect * from crm_fields where type = 'multi-picklist';\nSELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\nSELECT * FROM crm_fields WHERE id = 3014; # 1885\nSELECT * FROM crm_field_values WHERE crm_field_id = 3014;","depth":4,"on_screen":true,"value":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\n\nselect sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id\nwhere u.team_id = 1;\nSELECT * FROM social_accounts WHERE sociable_id = 1635;\nSELECT * FROM users WHERE id = 1635;\n\nselect * from teams where id = 1;\nselect * from users where team_id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role;\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\nSELECT * FROM automated_reports where id = 71;\nSELECT * FROM automated_report_results where report_id = 71;\nUPDATE automated_reports set playbook_categories = NULL where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT `automated_report_results`.* FROM `automated_report_results`\nINNER JOIN `automated_reports`\n ON `automated_report_results`.`report_id` = `automated_reports`.`id`\nWHERE 1=1\n AND `automated_report_results`.`generated_at` IS NOT NULL\n# AND `automated_report_results`.`sent_at` IS NOT NULL\n AND `automated_reports`.`team_id` = 1\n AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$.\"users\"')\n;\n\nSELECT * FROM automated_reports where id = 67;\nSELECT * FROM automated_reports where id = 42;\nSELECT * FROM users WHERE id = 143; # group 28\n\nselect * from teams where id = 3143;\nselect * from crm_configurations where id = 500;\nselect * from users where name = 'Integration Account'; # 1695\nSELECT * FROM social_accounts WHERE sociable_id = 1695;\n\nselect * from activities where crm_configuration_id = 39\nand recording_state = 'recorded' and duration > 60\nand status = 'completed' and actual_start_time >= '2025-12-01';\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;\n\nselect * from leads;\n\nSELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003\nSELECT * FROM activities WHERE id IN (16,422003);\nSELECT * FROM activities where status = 'failed';\n\nSELECT * FROM tracks WHERE activity_id = 422003;\n\nSELECT\n a.*\nFROM activities a\nJOIN users u ON a.user_id = u.id\nWHERE\n a.status = 'completed'\n AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid\n AND a.deleted_at IS NULL\n AND EXISTS (\n SELECT 1 FROM tracks t\n WHERE t.activity_id = a.id\n AND t.type IN ('audio', 'video')\n )\nORDER BY a.actual_start_time DESC\nLIMIT 25;\n\nselect * from teams where id = 19;\nselect * from crm_configurations where provider = 'pipedrive';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 19 and sa.provider = 'pipedrive';\n\nSELECT * FROM social_accounts WHERE id = 1116;\n\nUPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',\nprovider_refresh_token = '5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc',\nexpires = 1779091997,\nstate = 'connected'\nWHERE id = 1116;\n\n \"provider_user_token\": \"v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA\",\n \"provider_refresh_token\": \"5034113:19555731:87c14258f0c813d02767ee975f6044d46b6b2bfc\",\n \"expires\": 1779091997,\n\nselect * from crm_field_values;\n\nselect * from crm_fields where type = 'multi-picklist';\nSELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\nSELECT * FROM crm_fields WHERE id = 3014; # 1885\nSELECT * FROM crm_field_values WHERE crm_field_id = 3014;","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"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}]...
|
8673302249742970920
|
6685203931303450205
|
typing_pause
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
42
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models\Crm;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Jiminny\Component\Eloquent\Builder;
use Jiminny\Models\Ai\CrmTemplateField;
use Jiminny\Models\Model;
use Jiminny\Models\Playbook;
use Jiminny\Services\Crm\CrmObjects\FieldReadonlyConstants;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
/**
* Jiminny\Models\Crm\Field
*
* @property int $id
* @property mixed|null $uuid
* @property int $crm_configuration_id
* @property string $crm_provider_id
* @property string $label
* @property string|null $description
* @property string $type
* @property int|null $length
* @property string|null $default_value
* @property string $object_type
* @property bool $is_selectable
* @property bool $is_mandatory
* @property bool $is_filterable
* @property bool $is_indexable
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Jiminny\Models\Crm\Configuration $configuration
* @property-read \Jiminny\Models\Crm\Configuration $crm
* @property-read Collection<int, \Jiminny\Models\Crm\FieldData> $data
* @property-read int|null $data_count
* @property-read Collection<int, \Jiminny\Models\Crm\LayoutEntity> $entities
* @property-read int|null $entities_count
* @property-read string $id_string
* @property-read Collection<int, \Jiminny\Models\Crm\FieldValue> $values
* @property-read int|null $values_count
*
* @method static Builder|Field chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\Crm\FieldFactory factory(...$parameters)
* @method static Builder|Field idOrUuId($idOrUuid, bool $first = true)
* @method static Builder|Field indexable()
* @method static Builder|Field newModelQuery()
* @method static Builder|Field newQuery()
* @method static Builder|Field query()
* @method static Builder|Field tasks()
* @method static Builder|Field uuid(string $uuid, bool $first = true)
* @method static Builder|Field whereCreatedAt($value)
* @method static Builder|Field whereCrmConfigurationId($value)
* @method static Builder|Field whereCrmProviderId($value)
* @method static Builder|Field whereDefaultValue($value)
* @method static Builder|Field whereDescription($value)
* @method static Builder|Field whereId($value)
* @method static Builder|Field whereIsFilterable($value)
* @method static Builder|Field whereIsIndexable($value)
* @method static Builder|Field whereIsMandatory($value)
* @method static Builder|Field whereIsSelectable($value)
* @method static Builder|Field whereLabel($value)
* @method static Builder|Field whereLength($value)
* @method static Builder|Field whereObjectType($value)
* @method static Builder|Field whereType($value)
* @method static Builder|Field whereUpdatedAt($value)
* @method static Builder|Field whereUuid($value)
*
* @mixin \Eloquent
*/
class Field extends Model
{
use HasFactory;
use RequiresUUID;
use Enums;
public const int NAME_MAX_LENGTH = 128;
public const int LABEL_MAX_LENGTH = 255;
public const int DESCRIPTION_MAX_LENGTH = 191;
public const string TYPE_MULTIPICKLIST = 'multi-picklist';
// Not yet supported
public const string TYPE_PERCENT = 'percent';
public const string TYPE_PICKLIST = 'picklist';
public const string TYPE_NUMBER = 'number';
public const string TYPE_CURRENCY = 'currency';
public const string TYPE_BOOLEAN = 'boolean';
public const string TYPE_TEXT = 'text';
public const string TYPE_TEXTAREA = 'textarea';
public const string TYPE_EMAIL = 'email';
public const string TYPE_PHONE = 'phone';
public const string TYPE_URL = 'url';
public const string TYPE_DATE = 'date';
public const string TYPE_TIME = 'time';
public const string TYPE_DATETIME = 'datetime';
public const string TYPE_UNSUPPORTED = 'unsupported';
public const string OBJECT_LEAD = 'lead';
public const string OBJECT_ACCOUNT = 'account';
public const string OBJECT_CONTACT = 'contact';
public const string OBJECT_OPPORTUNITY = 'opportunity';
public const string OBJECT_TASK = 'task';
public const string OBJECT_EVENT = 'event';
public const string OBJECT_CALL = 'call';
public const string OBJECT_MEETING = 'meeting';
public const array BUSINESS_TYPE_FIELDS = [
Configuration::PROVIDER_SALESFORCE => 'Type',
Configuration::PROVIDER_HUBSPOT => 'dealtype',
];
public const array PIPELINE_TYPE_FIELDS = [
Configuration::PROVIDER_HUBSPOT => 'pipeline',
];
public const array STAGE_TYPE_FIELDS = [
Configuration::PROVIDER_SALESFORCE => 'StageName',
Configuration::PROVIDER_HUBSPOT => 'dealstage',
Configuration::PROVIDER_CLOSE => 'status_id',
Configuration::PROVIDER_BULLHORN => 'status',
Configuration::PROVIDER_PIPEDRIVE => 'stage_id',
Configuration::PROVIDER_COPPER => 'pipeline_stage_id',
];
public static $enumTypes = [
self::TYPE_PICKLIST,
self::TYPE_NUMBER,
self::TYPE_CURRENCY,
self::TYPE_BOOLEAN,
self::TYPE_TEXT,
self::TYPE_TEXTAREA,
self::TYPE_EMAIL,
self::TYPE_PHONE,
self::TYPE_URL,
self::TYPE_DATE,
self::TYPE_TIME,
self::TYPE_DATETIME,
self::TYPE_UNSUPPORTED,
];
public static $enumObjectTypes = [
self::OBJECT_LEAD,
self::OBJECT_ACCOUNT,
self::OBJECT_CONTACT,
self::OBJECT_OPPORTUNITY,
self::OBJECT_TASK,
self::OBJECT_EVENT,
];
protected $table = 'crm_fields';
protected $fillable = [
'crm_configuration_id',
'crm_provider_id',
'object_type',
'type',
'label',
'description',
'is_selectable',
'is_mandatory',
'length',
'default_value',
'is_indexable',
'is_filterable',
'is_readonly',
];
protected $appends = [
'id_string',
];
protected $hidden = [
'uuid',
'id',
'crm_configuration_id',
];
protected function casts(): array
{
return [
'is_selectable' => 'boolean',
'is_mandatory' => 'boolean',
'is_indexable' => 'boolean',
'is_filterable' => 'boolean',
];
}
public function configuration(): BelongsTo
{
return $this->belongsTo(Configuration::class, 'crm_configuration_id');
}
public function entities(): HasMany
{
return $this->hasMany(LayoutEntity::class, 'crm_field_id');
}
public function getEntities(): Collection
{
/** @var Collection<LayoutEntity> $entities */
$entities = $this->getAttribute('entities');
return $entities;
}
public function values(): HasMany
{
return $this->hasMany(FieldValue::class, 'crm_field_id')->orderBy('sequence');
}
public function getLabel(): string
{
return $this->getAttribute('label');
}
public function getType(): string
{
return $this->getAttribute('type');
}
public function getObjectType(): string
{
/** @var string */
return $this->getAttribute('object_type');
}
public function getCrmProviderId(): string
{
/** @var string */
return $this->getAttribute('crm_provider_id');
}
public function getValues(): Collection
{
return $this->getAttribute('values');
}
public function isIndexable(): bool
{
return $this->getAttribute('is_indexable');
}
public function isFilterable(): bool
{
return $this->getAttribute('is_filterable');
}
public function getId(): int
{
/** @var int */
return $this->getAttribute('id');
}
public function hasDescription(): bool
{
return $this->getAttribute('description') !== null;
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function data()
{
return $this->hasMany(FieldData::class, 'crm_field_id');
}
public function crm(): BelongsTo
{
return $this->belongsTo(Configuration::class, 'crm_configuration_id');
}
#[Scope]
protected function indexable($query)
{
return $query->where('is_indexable', 1);
}
#[Scope]
protected function tasks($query)
{
return $query->where('object_type', self::OBJECT_TASK);
}
public function isBusinessType(): bool
{
return in_array($this->getCrmProviderId(), self::BUSINESS_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function isStageField(): bool
{
return in_array($this->getCrmProviderId(), self::STAGE_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function isPipelineField(): bool
{
return in_array($this->getCrmProviderId(), self::PIPELINE_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function getUuid(): string
{
return $this->getAttribute('id_string');
}
public function getCrmConfiguration(): Configuration
{
return $this->getAttribute('crm');
}
public function getCrmConfigurationId(): int
{
return $this->getAttribute('crm_configuration_id');
}
/**
* Currently implemented only for Opportunity fields
*/
public function isReadOnly(): bool
{
// The CRM Field metadata should always be first to be taken into consideration.
if ($this->getIsReadonly()) {
return true;
}
if ($this->getObjectType() !== self::OBJECT_OPPORTUNITY) {
return false;
}
if ($this->isPipelineField()) {
return true;
}
if ($this->getType() === Field::TYPE_UNSUPPORTED) {
return true;
}
if ($this->getCrmConfiguration()->getProviderName() === Configuration::PROVIDER_INTEGRATION_APP) {
$fieldDefinitions = new CrmFieldDefinitionsManager();
return $fieldDefinitions->isReadOnly($this->getCrmProviderId(), self::OBJECT_OPPORTUNITY);
}
return false;
}
public function isPicklist(): bool
{
return in_array($this->getType(), [self::TYPE_PICKLIST, self::TYPE_MULTIPICKLIST]);
}
public function getLength(): ?int
{
return $this->getAttribute('length');
}
public function getDefaultValue(): ?string
{
return $this->getAttribute('default_value');
}
public function setIsReadonly(int $isReadonly): void
{
$this->setAttribute('is_readonly', $isReadonly);
}
public function getIsReadonly(): bool
{
return $this->getAttribute('is_readonly') !== FieldReadonlyConstants::FIELD_IS_UPDATABLE;
}
public function getEntityName(): string
{
return ucfirst($this->getObjectType()) . '.' . $this->getCrmProviderId();
}
public function crmTemplateFields(): HasMany
{
return $this->hasMany(CrmTemplateField::class, 'crm_field_id');
}
public function playbooks(): HasMany
{
return $this->hasMany(Playbook::class, 'activity_field_id');
}
public function getPlaybooks(): Collection
{
return $this->getAttribute('playbooks');
}
}
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
21
1
18
2
6
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select sa.* from users u JOIN social_accounts sa on u.id = sa.sociable_id
where u.team_id = 1;
SELECT * FROM social_accounts WHERE sociable_id = 1635;
SELECT * FROM users WHERE id = 1635;
select * from teams where id = 1;
select * from users where team_id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM activities WHERE uuid_to_bin('e916569b-086c-4bd1-94d7-5e3802c27ccf') = uuid;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role;
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
SELECT * FROM automated_reports where id = 71;
SELECT * FROM automated_report_results where report_id = 71;
UPDATE automated_reports set playbook_categories = NULL where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT `automated_report_results`.* FROM `automated_report_results`
INNER JOIN `automated_reports`
ON `automated_report_results`.`report_id` = `automated_reports`.`id`
WHERE 1=1
AND `automated_report_results`.`generated_at` IS NOT NULL
# AND `automated_report_results`.`sent_at` IS NOT NULL
AND `automated_reports`.`team_id` = 1
AND JSON_CONTAINS(`automated_reports`.`recipients`, 143, '$."users"')
;
SELECT * FROM automated_reports where id = 67;
SELECT * FROM automated_reports where id = 42;
SELECT * FROM users WHERE id = 143; # group 28
select * from teams where id = 3143;
select * from crm_configurations where id = 500;
select * from users where name = 'Integration Account'; # 1695
SELECT * FROM social_accounts WHERE sociable_id = 1695;
select * from activities where crm_configuration_id = 39
and recording_state = 'recorded' and duration > 60
and status = 'completed' and actual_start_time >= '2025-12-01';
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid;
select * from leads;
SELECT * FROM activities WHERE uuid_to_bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid; # 422003
SELECT * FROM activities WHERE id IN (16,422003);
SELECT * FROM activities where status = 'failed';
SELECT * FROM tracks WHERE activity_id = 422003;
SELECT
a.*
FROM activities a
JOIN users u ON a.user_id = u.id
WHERE
a.status = 'completed'
AND uuid_to_bin('641f1acb-16b8-42d1-8726-df52979dad0e') = u.uuid
AND a.deleted_at IS NULL
AND EXISTS (
SELECT 1 FROM tracks t
WHERE t.activity_id = a.id
AND t.type IN ('audio', 'video')
)
ORDER BY a.actual_start_time DESC
LIMIT 25;
select * from teams where id = 19;
select * from crm_configurations where provider = 'pipedrive';
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 = 19 and sa.provider = 'pipedrive';
SELECT * FROM social_accounts WHERE id = 1116;
UPDATE social_accounts SET provider_user_token = 'v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA',
provider_refresh_token = '5034113:[TELEGRAM_TOKEN]b2bfc',
expires = 1779091997,
state = 'connected'
WHERE id = 1116;
"provider_user_token": "v1u:AQIBAHj-LzTNK2yuuuaLqifzhWb9crUNKTpk4FlQ9rjnXqp_6AEQhDhDQVa1nvWCHEvnpvSEAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMnG8KNcZLIjEnlRPxAgEQgDsGPIcKjsMU7Qel36BtM5FCQa56mYUy24_AAoqd12yjVFkq6egLqS0inp-5G4JE7frJURMV8VTw_fY14g:rYyABXmXsBhEdYU_dfmDH8GF-vzSseJXE5bds_zAyVdAwlTXOPdTl9i4PS4jVofLvpq7IRgvEt2BzGhR6cWiQXHHD0AtayQOkZm262ClFCsMYtKGfep0Jq1n0eiRIVqT9gAY7rWvhpEDF8oAlgnRGmqx-euIkpzE79sPXh4OjNx_yUIaanjyplGpBBJ_NiACd1sMlZmseyUyyU_gldqlCBAuK9hhATc9icgg7zuoc7nKBBrlg49tRtzEagDh6xbFBpzfCp7kE_7n4TLWfWHLPMzu-bktjwA969G9sFRmoH1GjPA0a2odDT4dk1_1ouBrB1NcTT2hQUqH-_RzDW2nWmeoVHA",
"provider_refresh_token": "5034113:[TELEGRAM_TOKEN]b2bfc",
"expires": 1779091997,
select * from crm_field_values;
select * from crm_fields where type = 'multi-picklist';
SELECT * FROM crm_layouts WHERE uuid_to_bin('7c327871-fc25-4c56-9a0f-44c5a849d65c') = uuid;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
SELECT * FROM crm_fields WHERE id = 3014; # 1885
SELECT * FROM crm_field_values WHERE crm_field_id = 3014;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79488
|
2786
|
32
|
2026-05-28T06:31:36.850646+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949896850_m1.jpg...
|
PhpStorm
|
faVsco.js – SF [jiminny@localhost]
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
42
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models\Crm;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Jiminny\Component\Eloquent\Builder;
use Jiminny\Models\Ai\CrmTemplateField;
use Jiminny\Models\Model;
use Jiminny\Models\Playbook;
use Jiminny\Services\Crm\CrmObjects\FieldReadonlyConstants;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
/**
* Jiminny\Models\Crm\Field
*
* @property int $id
* @property mixed|null $uuid
* @property int $crm_configuration_id
* @property string $crm_provider_id
* @property string $label
* @property string|null $description
* @property string $type
* @property int|null $length
* @property string|null $default_value
* @property string $object_type
* @property bool $is_selectable
* @property bool $is_mandatory
* @property bool $is_filterable
* @property bool $is_indexable
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Jiminny\Models\Crm\Configuration $configuration
* @property-read \Jiminny\Models\Crm\Configuration $crm
* @property-read Collection<int, \Jiminny\Models\Crm\FieldData> $data
* @property-read int|null $data_count
* @property-read Collection<int, \Jiminny\Models\Crm\LayoutEntity> $entities
* @property-read int|null $entities_count
* @property-read string $id_string
* @property-read Collection<int, \Jiminny\Models\Crm\FieldValue> $values
* @property-read int|null $values_count
*
* @method static Builder|Field chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\Crm\FieldFactory factory(...$parameters)
* @method static Builder|Field idOrUuId($idOrUuid, bool $first = true)
* @method static Builder|Field indexable()
* @method static Builder|Field newModelQuery()
* @method static Builder|Field newQuery()
* @method static Builder|Field query()
* @method static Builder|Field tasks()
* @method static Builder|Field uuid(string $uuid, bool $first = true)
* @method static Builder|Field whereCreatedAt($value)
* @method static Builder|Field whereCrmConfigurationId($value)
* @method static Builder|Field whereCrmProviderId($value)
* @method static Builder|Field whereDefaultValue($value)
* @method static Builder|Field whereDescription($value)
* @method static Builder|Field whereId($value)
* @method static Builder|Field whereIsFilterable($value)
* @method static Builder|Field whereIsIndexable($value)
* @method static Builder|Field whereIsMandatory($value)
* @method static Builder|Field whereIsSelectable($value)
* @method static Builder|Field whereLabel($value)
* @method static Builder|Field whereLength($value)
* @method static Builder|Field whereObjectType($value)
* @method static Builder|Field whereType($value)
* @method static Builder|Field whereUpdatedAt($value)
* @method static Builder|Field whereUuid($value)
*
* @mixin \Eloquent
*/
class Field extends Model
{
use HasFactory;
use RequiresUUID;
use Enums;
public const int NAME_MAX_LENGTH = 128;
public const int LABEL_MAX_LENGTH = 255;
public const int DESCRIPTION_MAX_LENGTH = 191;
public const string TYPE_MULTIPICKLIST = 'multi-picklist';
// Not yet supported
public const string TYPE_PERCENT = 'percent';
public const string TYPE_PICKLIST = 'picklist';
public const string TYPE_NUMBER = 'number';
public const string TYPE_CURRENCY = 'currency';
public const string TYPE_BOOLEAN = 'boolean';
public const string TYPE_TEXT = 'text';
public const string TYPE_TEXTAREA = 'textarea';
public const string TYPE_EMAIL = 'email';
public const string TYPE_PHONE = 'phone';
public const string TYPE_URL = 'url';
public const string TYPE_DATE = 'date';
public const string TYPE_TIME = 'time';
public const string TYPE_DATETIME = 'datetime';
public const string TYPE_UNSUPPORTED = 'unsupported';
public const string OBJECT_LEAD = 'lead';
public const string OBJECT_ACCOUNT = 'account';
public const string OBJECT_CONTACT = 'contact';
public const string OBJECT_OPPORTUNITY = 'opportunity';
public const string OBJECT_TASK = 'task';
public const string OBJECT_EVENT = 'event';
public const string OBJECT_CALL = 'call';
public const string OBJECT_MEETING = 'meeting';
public const array BUSINESS_TYPE_FIELDS = [
Configuration::PROVIDER_SALESFORCE => 'Type',
Configuration::PROVIDER_HUBSPOT => 'dealtype',
];
public const array PIPELINE_TYPE_FIELDS = [
Configuration::PROVIDER_HUBSPOT => 'pipeline',
];
public const array STAGE_TYPE_FIELDS = [
Configuration::PROVIDER_SALESFORCE => 'StageName',
Configuration::PROVIDER_HUBSPOT => 'dealstage',
Configuration::PROVIDER_CLOSE => 'status_id',
Configuration::PROVIDER_BULLHORN => 'status',
Configuration::PROVIDER_PIPEDRIVE => 'stage_id',
Configuration::PROVIDER_COPPER => 'pipeline_stage_id',
];
public static $enumTypes = [
self::TYPE_PICKLIST,
self::TYPE_NUMBER,
self::TYPE_CURRENCY,
self::TYPE_BOOLEAN,
self::TYPE_TEXT,
self::TYPE_TEXTAREA,
self::TYPE_EMAIL,
self::TYPE_PHONE,
self::TYPE_URL,
self::TYPE_DATE,
self::TYPE_TIME,
self::TYPE_DATETIME,
self::TYPE_UNSUPPORTED,
];
public static $enumObjectTypes = [
self::OBJECT_LEAD,
self::OBJECT_ACCOUNT,
self::OBJECT_CONTACT,
self::OBJECT_OPPORTUNITY,
self::OBJECT_TASK,
self::OBJECT_EVENT,
];
protected $table = 'crm_fields';
protected $fillable = [
'crm_configuration_id',
'crm_provider_id',
'object_type',
'type',
'label',
'description',
'is_selectable',
'is_mandatory',
'length',
'default_value',
'is_indexable',
'is_filterable',
'is_readonly',
];
protected $appends = [
'id_string',
];
protected $hidden = [
'uuid',
'id',
'crm_configuration_id',
];
protected function casts(): array
{
return [
'is_selectable' => 'boolean',
'is_mandatory' => 'boolean',
'is_indexable' => 'boolean',
'is_filterable' => 'boolean',
];
}
public function configuration(): BelongsTo
{
return $this->belongsTo(Configuration::class, 'crm_configuration_id');
}
public function entities(): HasMany
{
return $this->hasMany(LayoutEntity::class, 'crm_field_id');
}
public function getEntities(): Collection
{
/** @var Collection<LayoutEntity> $entities */
$entities = $this->getAttribute('entities');
return $entities;
}
public function values(): HasMany
{
return $this->hasMany(FieldValue::class, 'crm_field_id')->orderBy('sequence');
}
public function getLabel(): string
{
return $this->getAttribute('label');
}
public function getType(): string
{
return $this->getAttribute('type');
}
public function getObjectType(): string
{
/** @var string */
return $this->getAttribute('object_type');
}
public function getCrmProviderId(): string
{
/** @var string */
return $this->getAttribute('crm_provider_id');
}
public function getValues(): Collection
{
return $this->getAttribute('values');
}
public function isIndexable(): bool
{
return $this->getAttribute('is_indexable');
}
public function isFilterable(): bool
{
return $this->getAttribute('is_filterable');
}
public function getId(): int
{
/** @var int */
return $this->getAttribute('id');
}
public function hasDescription(): bool
{
return $this->getAttribute('description') !== null;
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function data()
{
return $this->hasMany(FieldData::class, 'crm_field_id');
}
public function crm(): BelongsTo
{
return $this->belongsTo(Configuration::class, 'crm_configuration_id');
}
#[Scope]
protected function indexable($query)
{
return $query->where('is_indexable', 1);
}
#[Scope]
protected function tasks($query)
{
return $query->where('object_type', self::OBJECT_TASK);
}
public function isBusinessType(): bool
{
return in_array($this->getCrmProviderId(), self::BUSINESS_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function isStageField(): bool
{
return in_array($this->getCrmProviderId(), self::STAGE_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function isPipelineField(): bool
{
return in_array($this->getCrmProviderId(), self::PIPELINE_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function getUuid(): string
{
return $this->getAttribute('id_string');
}
public function getCrmConfiguration(): Configuration
{
return $this->getAttribute('crm');
}
public function getCrmConfigurationId(): int
{
return $this->getAttribute('crm_configuration_id');
}
/**
* Currently implemented only for Opportunity fields
*/
public function isReadOnly(): bool
{
// The CRM Field metadata should always be first to be taken into consideration.
if ($this->getIsReadonly()) {
return true;
}
if ($this->getObjectType() !== self::OBJECT_OPPORTUNITY) {
return false;
}
if ($this->isPipelineField()) {
return true;
}
if ($this->getType() === Field::TYPE_UNSUPPORTED) {
return true;
}
if ($this->getCrmConfiguration()->getProviderName() === Configuration::PROVIDER_INTEGRATION_APP) {
$fieldDefinitions = new CrmFieldDefinitionsManager();
return $fieldDefinitions->isReadOnly($this->getCrmProviderId(), self::OBJECT_OPPORTUNITY);
}
return false;
}
public function isPicklist(): bool
{
return in_array($this->getType(), [self::TYPE_PICKLIST, self::TYPE_MULTIPICKLIST]);
}
public function getLength(): ?int
{
return $this->getAttribute('length');
}
public function getDefaultValue(): ?string
{
return $this->getAttribute('default_value');
}
public function setIsReadonly(int $isReadonly): void
{
$this->setAttribute('is_readonly', $isReadonly);
}
public function getIsReadonly(): bool
{
return $this->getAttribute('is_readonly') !== FieldReadonlyConstants::FIELD_IS_UPDATABLE;
}
public function getEntityName(): string
{
return ucfirst($this->getObjectType()) . '.' . $this->getCrmProviderId();
}
public function crmTemplateFields(): HasMany
{
return $this->hasMany(CrmTemplateField::class, 'crm_field_id');
}
public function playbooks(): HasMany
{
return $this->hasMany(Playbook::class, 'activity_field_id');
}
public function getPlaybooks(): Collection
{
return $this->getAttribute('playbooks');
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20915-fix-missing-header-text-relay, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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":"TextRelayServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'TextRelayServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'TextRelayServiceTest'","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":"42","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Models\\Crm;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Jiminny\\Component\\Eloquent\\Builder;\nuse Jiminny\\Models\\Ai\\CrmTemplateField;\nuse Jiminny\\Models\\Model;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Services\\Crm\\CrmObjects\\FieldReadonlyConstants;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\n\n/**\n * Jiminny\\Models\\Crm\\Field\n *\n * @property int $id\n * @property mixed|null $uuid\n * @property int $crm_configuration_id\n * @property string $crm_provider_id\n * @property string $label\n * @property string|null $description\n * @property string $type\n * @property int|null $length\n * @property string|null $default_value\n * @property string $object_type\n * @property bool $is_selectable\n * @property bool $is_mandatory\n * @property bool $is_filterable\n * @property bool $is_indexable\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property-read \\Jiminny\\Models\\Crm\\Configuration $configuration\n * @property-read \\Jiminny\\Models\\Crm\\Configuration $crm\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\FieldData> $data\n * @property-read int|null $data_count\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\LayoutEntity> $entities\n * @property-read int|null $entities_count\n * @property-read string $id_string\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\FieldValue> $values\n * @property-read int|null $values_count\n *\n * @method static Builder|Field chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\Crm\\FieldFactory factory(...$parameters)\n * @method static Builder|Field idOrUuId($idOrUuid, bool $first = true)\n * @method static Builder|Field indexable()\n * @method static Builder|Field newModelQuery()\n * @method static Builder|Field newQuery()\n * @method static Builder|Field query()\n * @method static Builder|Field tasks()\n * @method static Builder|Field uuid(string $uuid, bool $first = true)\n * @method static Builder|Field whereCreatedAt($value)\n * @method static Builder|Field whereCrmConfigurationId($value)\n * @method static Builder|Field whereCrmProviderId($value)\n * @method static Builder|Field whereDefaultValue($value)\n * @method static Builder|Field whereDescription($value)\n * @method static Builder|Field whereId($value)\n * @method static Builder|Field whereIsFilterable($value)\n * @method static Builder|Field whereIsIndexable($value)\n * @method static Builder|Field whereIsMandatory($value)\n * @method static Builder|Field whereIsSelectable($value)\n * @method static Builder|Field whereLabel($value)\n * @method static Builder|Field whereLength($value)\n * @method static Builder|Field whereObjectType($value)\n * @method static Builder|Field whereType($value)\n * @method static Builder|Field whereUpdatedAt($value)\n * @method static Builder|Field whereUuid($value)\n *\n * @mixin \\Eloquent\n */\nclass Field extends Model\n{\n use HasFactory;\n\n use RequiresUUID;\n use Enums;\n\n public const int NAME_MAX_LENGTH = 128;\n public const int LABEL_MAX_LENGTH = 255;\n public const int DESCRIPTION_MAX_LENGTH = 191;\n\n public const string TYPE_MULTIPICKLIST = 'multi-picklist';\n // Not yet supported\n public const string TYPE_PERCENT = 'percent';\n\n public const string TYPE_PICKLIST = 'picklist';\n public const string TYPE_NUMBER = 'number';\n public const string TYPE_CURRENCY = 'currency';\n public const string TYPE_BOOLEAN = 'boolean';\n public const string TYPE_TEXT = 'text';\n public const string TYPE_TEXTAREA = 'textarea';\n public const string TYPE_EMAIL = 'email';\n public const string TYPE_PHONE = 'phone';\n public const string TYPE_URL = 'url';\n public const string TYPE_DATE = 'date';\n public const string TYPE_TIME = 'time';\n public const string TYPE_DATETIME = 'datetime';\n public const string TYPE_UNSUPPORTED = 'unsupported';\n\n public const string OBJECT_LEAD = 'lead';\n public const string OBJECT_ACCOUNT = 'account';\n public const string OBJECT_CONTACT = 'contact';\n public const string OBJECT_OPPORTUNITY = 'opportunity';\n public const string OBJECT_TASK = 'task';\n public const string OBJECT_EVENT = 'event';\n public const string OBJECT_CALL = 'call';\n public const string OBJECT_MEETING = 'meeting';\n\n public const array BUSINESS_TYPE_FIELDS = [\n Configuration::PROVIDER_SALESFORCE => 'Type',\n Configuration::PROVIDER_HUBSPOT => 'dealtype',\n ];\n\n public const array PIPELINE_TYPE_FIELDS = [\n Configuration::PROVIDER_HUBSPOT => 'pipeline',\n ];\n\n public const array STAGE_TYPE_FIELDS = [\n Configuration::PROVIDER_SALESFORCE => 'StageName',\n Configuration::PROVIDER_HUBSPOT => 'dealstage',\n Configuration::PROVIDER_CLOSE => 'status_id',\n Configuration::PROVIDER_BULLHORN => 'status',\n Configuration::PROVIDER_PIPEDRIVE => 'stage_id',\n Configuration::PROVIDER_COPPER => 'pipeline_stage_id',\n ];\n\n public static $enumTypes = [\n self::TYPE_PICKLIST,\n self::TYPE_NUMBER,\n self::TYPE_CURRENCY,\n self::TYPE_BOOLEAN,\n self::TYPE_TEXT,\n self::TYPE_TEXTAREA,\n self::TYPE_EMAIL,\n self::TYPE_PHONE,\n self::TYPE_URL,\n self::TYPE_DATE,\n self::TYPE_TIME,\n self::TYPE_DATETIME,\n self::TYPE_UNSUPPORTED,\n ];\n\n public static $enumObjectTypes = [\n self::OBJECT_LEAD,\n self::OBJECT_ACCOUNT,\n self::OBJECT_CONTACT,\n self::OBJECT_OPPORTUNITY,\n self::OBJECT_TASK,\n self::OBJECT_EVENT,\n ];\n\n protected $table = 'crm_fields';\n\n protected $fillable = [\n 'crm_configuration_id',\n 'crm_provider_id',\n 'object_type',\n 'type',\n 'label',\n 'description',\n 'is_selectable',\n 'is_mandatory',\n 'length',\n 'default_value',\n 'is_indexable',\n 'is_filterable',\n 'is_readonly',\n ];\n\n protected $appends = [\n 'id_string',\n ];\n\n protected $hidden = [\n 'uuid',\n 'id',\n 'crm_configuration_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'is_selectable' => 'boolean',\n 'is_mandatory' => 'boolean',\n 'is_indexable' => 'boolean',\n 'is_filterable' => 'boolean',\n ];\n }\n\n public function configuration(): BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function entities(): HasMany\n {\n return $this->hasMany(LayoutEntity::class, 'crm_field_id');\n }\n\n public function getEntities(): Collection\n {\n /** @var Collection<LayoutEntity> $entities */\n $entities = $this->getAttribute('entities');\n\n return $entities;\n }\n\n public function values(): HasMany\n {\n return $this->hasMany(FieldValue::class, 'crm_field_id')->orderBy('sequence');\n }\n\n public function getLabel(): string\n {\n return $this->getAttribute('label');\n }\n\n public function getType(): string\n {\n return $this->getAttribute('type');\n }\n\n public function getObjectType(): string\n {\n /** @var string */\n return $this->getAttribute('object_type');\n }\n\n public function getCrmProviderId(): string\n {\n /** @var string */\n return $this->getAttribute('crm_provider_id');\n }\n\n public function getValues(): Collection\n {\n return $this->getAttribute('values');\n }\n\n public function isIndexable(): bool\n {\n return $this->getAttribute('is_indexable');\n }\n\n public function isFilterable(): bool\n {\n return $this->getAttribute('is_filterable');\n }\n\n public function getId(): int\n {\n /** @var int */\n return $this->getAttribute('id');\n }\n\n public function hasDescription(): bool\n {\n return $this->getAttribute('description') !== null;\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function data()\n {\n return $this->hasMany(FieldData::class, 'crm_field_id');\n }\n\n public function crm(): BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n #[Scope]\n protected function indexable($query)\n {\n return $query->where('is_indexable', 1);\n }\n\n #[Scope]\n protected function tasks($query)\n {\n return $query->where('object_type', self::OBJECT_TASK);\n }\n\n public function isBusinessType(): bool\n {\n return in_array($this->getCrmProviderId(), self::BUSINESS_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function isStageField(): bool\n {\n return in_array($this->getCrmProviderId(), self::STAGE_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function isPipelineField(): bool\n {\n return in_array($this->getCrmProviderId(), self::PIPELINE_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getCrmConfiguration(): Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function getCrmConfigurationId(): int\n {\n return $this->getAttribute('crm_configuration_id');\n }\n\n /**\n * Currently implemented only for Opportunity fields\n */\n public function isReadOnly(): bool\n {\n // The CRM Field metadata should always be first to be taken into consideration.\n if ($this->getIsReadonly()) {\n return true;\n }\n\n if ($this->getObjectType() !== self::OBJECT_OPPORTUNITY) {\n return false;\n }\n\n if ($this->isPipelineField()) {\n return true;\n }\n\n if ($this->getType() === Field::TYPE_UNSUPPORTED) {\n return true;\n }\n\n if ($this->getCrmConfiguration()->getProviderName() === Configuration::PROVIDER_INTEGRATION_APP) {\n $fieldDefinitions = new CrmFieldDefinitionsManager();\n\n return $fieldDefinitions->isReadOnly($this->getCrmProviderId(), self::OBJECT_OPPORTUNITY);\n }\n\n return false;\n }\n\n public function isPicklist(): bool\n {\n return in_array($this->getType(), [self::TYPE_PICKLIST, self::TYPE_MULTIPICKLIST]);\n }\n\n public function getLength(): ?int\n {\n return $this->getAttribute('length');\n }\n\n public function getDefaultValue(): ?string\n {\n return $this->getAttribute('default_value');\n }\n\n public function setIsReadonly(int $isReadonly): void\n {\n $this->setAttribute('is_readonly', $isReadonly);\n }\n\n public function getIsReadonly(): bool\n {\n return $this->getAttribute('is_readonly') !== FieldReadonlyConstants::FIELD_IS_UPDATABLE;\n }\n\n public function getEntityName(): string\n {\n return ucfirst($this->getObjectType()) . '.' . $this->getCrmProviderId();\n }\n\n public function crmTemplateFields(): HasMany\n {\n return $this->hasMany(CrmTemplateField::class, 'crm_field_id');\n }\n\n public function playbooks(): HasMany\n {\n return $this->hasMany(Playbook::class, 'activity_field_id');\n }\n\n public function getPlaybooks(): Collection\n {\n return $this->getAttribute('playbooks');\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Models\\Crm;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Jiminny\\Component\\Eloquent\\Builder;\nuse Jiminny\\Models\\Ai\\CrmTemplateField;\nuse Jiminny\\Models\\Model;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Services\\Crm\\CrmObjects\\FieldReadonlyConstants;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\n\n/**\n * Jiminny\\Models\\Crm\\Field\n *\n * @property int $id\n * @property mixed|null $uuid\n * @property int $crm_configuration_id\n * @property string $crm_provider_id\n * @property string $label\n * @property string|null $description\n * @property string $type\n * @property int|null $length\n * @property string|null $default_value\n * @property string $object_type\n * @property bool $is_selectable\n * @property bool $is_mandatory\n * @property bool $is_filterable\n * @property bool $is_indexable\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property-read \\Jiminny\\Models\\Crm\\Configuration $configuration\n * @property-read \\Jiminny\\Models\\Crm\\Configuration $crm\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\FieldData> $data\n * @property-read int|null $data_count\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\LayoutEntity> $entities\n * @property-read int|null $entities_count\n * @property-read string $id_string\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\FieldValue> $values\n * @property-read int|null $values_count\n *\n * @method static Builder|Field chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\Crm\\FieldFactory factory(...$parameters)\n * @method static Builder|Field idOrUuId($idOrUuid, bool $first = true)\n * @method static Builder|Field indexable()\n * @method static Builder|Field newModelQuery()\n * @method static Builder|Field newQuery()\n * @method static Builder|Field query()\n * @method static Builder|Field tasks()\n * @method static Builder|Field uuid(string $uuid, bool $first = true)\n * @method static Builder|Field whereCreatedAt($value)\n * @method static Builder|Field whereCrmConfigurationId($value)\n * @method static Builder|Field whereCrmProviderId($value)\n * @method static Builder|Field whereDefaultValue($value)\n * @method static Builder|Field whereDescription($value)\n * @method static Builder|Field whereId($value)\n * @method static Builder|Field whereIsFilterable($value)\n * @method static Builder|Field whereIsIndexable($value)\n * @method static Builder|Field whereIsMandatory($value)\n * @method static Builder|Field whereIsSelectable($value)\n * @method static Builder|Field whereLabel($value)\n * @method static Builder|Field whereLength($value)\n * @method static Builder|Field whereObjectType($value)\n * @method static Builder|Field whereType($value)\n * @method static Builder|Field whereUpdatedAt($value)\n * @method static Builder|Field whereUuid($value)\n *\n * @mixin \\Eloquent\n */\nclass Field extends Model\n{\n use HasFactory;\n\n use RequiresUUID;\n use Enums;\n\n public const int NAME_MAX_LENGTH = 128;\n public const int LABEL_MAX_LENGTH = 255;\n public const int DESCRIPTION_MAX_LENGTH = 191;\n\n public const string TYPE_MULTIPICKLIST = 'multi-picklist';\n // Not yet supported\n public const string TYPE_PERCENT = 'percent';\n\n public const string TYPE_PICKLIST = 'picklist';\n public const string TYPE_NUMBER = 'number';\n public const string TYPE_CURRENCY = 'currency';\n public const string TYPE_BOOLEAN = 'boolean';\n public const string TYPE_TEXT = 'text';\n public const string TYPE_TEXTAREA = 'textarea';\n public const string TYPE_EMAIL = 'email';\n public const string TYPE_PHONE = 'phone';\n public const string TYPE_URL = 'url';\n public const string TYPE_DATE = 'date';\n public const string TYPE_TIME = 'time';\n public const string TYPE_DATETIME = 'datetime';\n public const string TYPE_UNSUPPORTED = 'unsupported';\n\n public const string OBJECT_LEAD = 'lead';\n public const string OBJECT_ACCOUNT = 'account';\n public const string OBJECT_CONTACT = 'contact';\n public const string OBJECT_OPPORTUNITY = 'opportunity';\n public const string OBJECT_TASK = 'task';\n public const string OBJECT_EVENT = 'event';\n public const string OBJECT_CALL = 'call';\n public const string OBJECT_MEETING = 'meeting';\n\n public const array BUSINESS_TYPE_FIELDS = [\n Configuration::PROVIDER_SALESFORCE => 'Type',\n Configuration::PROVIDER_HUBSPOT => 'dealtype',\n ];\n\n public const array PIPELINE_TYPE_FIELDS = [\n Configuration::PROVIDER_HUBSPOT => 'pipeline',\n ];\n\n public const array STAGE_TYPE_FIELDS = [\n Configuration::PROVIDER_SALESFORCE => 'StageName',\n Configuration::PROVIDER_HUBSPOT => 'dealstage',\n Configuration::PROVIDER_CLOSE => 'status_id',\n Configuration::PROVIDER_BULLHORN => 'status',\n Configuration::PROVIDER_PIPEDRIVE => 'stage_id',\n Configuration::PROVIDER_COPPER => 'pipeline_stage_id',\n ];\n\n public static $enumTypes = [\n self::TYPE_PICKLIST,\n self::TYPE_NUMBER,\n self::TYPE_CURRENCY,\n self::TYPE_BOOLEAN,\n self::TYPE_TEXT,\n self::TYPE_TEXTAREA,\n self::TYPE_EMAIL,\n self::TYPE_PHONE,\n self::TYPE_URL,\n self::TYPE_DATE,\n self::TYPE_TIME,\n self::TYPE_DATETIME,\n self::TYPE_UNSUPPORTED,\n ];\n\n public static $enumObjectTypes = [\n self::OBJECT_LEAD,\n self::OBJECT_ACCOUNT,\n self::OBJECT_CONTACT,\n self::OBJECT_OPPORTUNITY,\n self::OBJECT_TASK,\n self::OBJECT_EVENT,\n ];\n\n protected $table = 'crm_fields';\n\n protected $fillable = [\n 'crm_configuration_id',\n 'crm_provider_id',\n 'object_type',\n 'type',\n 'label',\n 'description',\n 'is_selectable',\n 'is_mandatory',\n 'length',\n 'default_value',\n 'is_indexable',\n 'is_filterable',\n 'is_readonly',\n ];\n\n protected $appends = [\n 'id_string',\n ];\n\n protected $hidden = [\n 'uuid',\n 'id',\n 'crm_configuration_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'is_selectable' => 'boolean',\n 'is_mandatory' => 'boolean',\n 'is_indexable' => 'boolean',\n 'is_filterable' => 'boolean',\n ];\n }\n\n public function configuration(): BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function entities(): HasMany\n {\n return $this->hasMany(LayoutEntity::class, 'crm_field_id');\n }\n\n public function getEntities(): Collection\n {\n /** @var Collection<LayoutEntity> $entities */\n $entities = $this->getAttribute('entities');\n\n return $entities;\n }\n\n public function values(): HasMany\n {\n return $this->hasMany(FieldValue::class, 'crm_field_id')->orderBy('sequence');\n }\n\n public function getLabel(): string\n {\n return $this->getAttribute('label');\n }\n\n public function getType(): string\n {\n return $this->getAttribute('type');\n }\n\n public function getObjectType(): string\n {\n /** @var string */\n return $this->getAttribute('object_type');\n }\n\n public function getCrmProviderId(): string\n {\n /** @var string */\n return $this->getAttribute('crm_provider_id');\n }\n\n public function getValues(): Collection\n {\n return $this->getAttribute('values');\n }\n\n public function isIndexable(): bool\n {\n return $this->getAttribute('is_indexable');\n }\n\n public function isFilterable(): bool\n {\n return $this->getAttribute('is_filterable');\n }\n\n public function getId(): int\n {\n /** @var int */\n return $this->getAttribute('id');\n }\n\n public function hasDescription(): bool\n {\n return $this->getAttribute('description') !== null;\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function data()\n {\n return $this->hasMany(FieldData::class, 'crm_field_id');\n }\n\n public function crm(): BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n #[Scope]\n protected function indexable($query)\n {\n return $query->where('is_indexable', 1);\n }\n\n #[Scope]\n protected function tasks($query)\n {\n return $query->where('object_type', self::OBJECT_TASK);\n }\n\n public function isBusinessType(): bool\n {\n return in_array($this->getCrmProviderId(), self::BUSINESS_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function isStageField(): bool\n {\n return in_array($this->getCrmProviderId(), self::STAGE_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function isPipelineField(): bool\n {\n return in_array($this->getCrmProviderId(), self::PIPELINE_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getCrmConfiguration(): Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function getCrmConfigurationId(): int\n {\n return $this->getAttribute('crm_configuration_id');\n }\n\n /**\n * Currently implemented only for Opportunity fields\n */\n public function isReadOnly(): bool\n {\n // The CRM Field metadata should always be first to be taken into consideration.\n if ($this->getIsReadonly()) {\n return true;\n }\n\n if ($this->getObjectType() !== self::OBJECT_OPPORTUNITY) {\n return false;\n }\n\n if ($this->isPipelineField()) {\n return true;\n }\n\n if ($this->getType() === Field::TYPE_UNSUPPORTED) {\n return true;\n }\n\n if ($this->getCrmConfiguration()->getProviderName() === Configuration::PROVIDER_INTEGRATION_APP) {\n $fieldDefinitions = new CrmFieldDefinitionsManager();\n\n return $fieldDefinitions->isReadOnly($this->getCrmProviderId(), self::OBJECT_OPPORTUNITY);\n }\n\n return false;\n }\n\n public function isPicklist(): bool\n {\n return in_array($this->getType(), [self::TYPE_PICKLIST, self::TYPE_MULTIPICKLIST]);\n }\n\n public function getLength(): ?int\n {\n return $this->getAttribute('length');\n }\n\n public function getDefaultValue(): ?string\n {\n return $this->getAttribute('default_value');\n }\n\n public function setIsReadonly(int $isReadonly): void\n {\n $this->setAttribute('is_readonly', $isReadonly);\n }\n\n public function getIsReadonly(): bool\n {\n return $this->getAttribute('is_readonly') !== FieldReadonlyConstants::FIELD_IS_UPDATABLE;\n }\n\n public function getEntityName(): string\n {\n return ucfirst($this->getObjectType()) . '.' . $this->getCrmProviderId();\n }\n\n public function crmTemplateFields(): HasMany\n {\n return $this->hasMany(CrmTemplateField::class, 'crm_field_id');\n }\n\n public function playbooks(): HasMany\n {\n return $this->hasMany(Playbook::class, 'activity_field_id');\n }\n\n public function getPlaybooks(): Collection\n {\n return $this->getAttribute('playbooks');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
6458054629937925028
|
5771048316864018365
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
42
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models\Crm;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Jiminny\Component\Eloquent\Builder;
use Jiminny\Models\Ai\CrmTemplateField;
use Jiminny\Models\Model;
use Jiminny\Models\Playbook;
use Jiminny\Services\Crm\CrmObjects\FieldReadonlyConstants;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
/**
* Jiminny\Models\Crm\Field
*
* @property int $id
* @property mixed|null $uuid
* @property int $crm_configuration_id
* @property string $crm_provider_id
* @property string $label
* @property string|null $description
* @property string $type
* @property int|null $length
* @property string|null $default_value
* @property string $object_type
* @property bool $is_selectable
* @property bool $is_mandatory
* @property bool $is_filterable
* @property bool $is_indexable
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Jiminny\Models\Crm\Configuration $configuration
* @property-read \Jiminny\Models\Crm\Configuration $crm
* @property-read Collection<int, \Jiminny\Models\Crm\FieldData> $data
* @property-read int|null $data_count
* @property-read Collection<int, \Jiminny\Models\Crm\LayoutEntity> $entities
* @property-read int|null $entities_count
* @property-read string $id_string
* @property-read Collection<int, \Jiminny\Models\Crm\FieldValue> $values
* @property-read int|null $values_count
*
* @method static Builder|Field chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\Crm\FieldFactory factory(...$parameters)
* @method static Builder|Field idOrUuId($idOrUuid, bool $first = true)
* @method static Builder|Field indexable()
* @method static Builder|Field newModelQuery()
* @method static Builder|Field newQuery()
* @method static Builder|Field query()
* @method static Builder|Field tasks()
* @method static Builder|Field uuid(string $uuid, bool $first = true)
* @method static Builder|Field whereCreatedAt($value)
* @method static Builder|Field whereCrmConfigurationId($value)
* @method static Builder|Field whereCrmProviderId($value)
* @method static Builder|Field whereDefaultValue($value)
* @method static Builder|Field whereDescription($value)
* @method static Builder|Field whereId($value)
* @method static Builder|Field whereIsFilterable($value)
* @method static Builder|Field whereIsIndexable($value)
* @method static Builder|Field whereIsMandatory($value)
* @method static Builder|Field whereIsSelectable($value)
* @method static Builder|Field whereLabel($value)
* @method static Builder|Field whereLength($value)
* @method static Builder|Field whereObjectType($value)
* @method static Builder|Field whereType($value)
* @method static Builder|Field whereUpdatedAt($value)
* @method static Builder|Field whereUuid($value)
*
* @mixin \Eloquent
*/
class Field extends Model
{
use HasFactory;
use RequiresUUID;
use Enums;
public const int NAME_MAX_LENGTH = 128;
public const int LABEL_MAX_LENGTH = 255;
public const int DESCRIPTION_MAX_LENGTH = 191;
public const string TYPE_MULTIPICKLIST = 'multi-picklist';
// Not yet supported
public const string TYPE_PERCENT = 'percent';
public const string TYPE_PICKLIST = 'picklist';
public const string TYPE_NUMBER = 'number';
public const string TYPE_CURRENCY = 'currency';
public const string TYPE_BOOLEAN = 'boolean';
public const string TYPE_TEXT = 'text';
public const string TYPE_TEXTAREA = 'textarea';
public const string TYPE_EMAIL = 'email';
public const string TYPE_PHONE = 'phone';
public const string TYPE_URL = 'url';
public const string TYPE_DATE = 'date';
public const string TYPE_TIME = 'time';
public const string TYPE_DATETIME = 'datetime';
public const string TYPE_UNSUPPORTED = 'unsupported';
public const string OBJECT_LEAD = 'lead';
public const string OBJECT_ACCOUNT = 'account';
public const string OBJECT_CONTACT = 'contact';
public const string OBJECT_OPPORTUNITY = 'opportunity';
public const string OBJECT_TASK = 'task';
public const string OBJECT_EVENT = 'event';
public const string OBJECT_CALL = 'call';
public const string OBJECT_MEETING = 'meeting';
public const array BUSINESS_TYPE_FIELDS = [
Configuration::PROVIDER_SALESFORCE => 'Type',
Configuration::PROVIDER_HUBSPOT => 'dealtype',
];
public const array PIPELINE_TYPE_FIELDS = [
Configuration::PROVIDER_HUBSPOT => 'pipeline',
];
public const array STAGE_TYPE_FIELDS = [
Configuration::PROVIDER_SALESFORCE => 'StageName',
Configuration::PROVIDER_HUBSPOT => 'dealstage',
Configuration::PROVIDER_CLOSE => 'status_id',
Configuration::PROVIDER_BULLHORN => 'status',
Configuration::PROVIDER_PIPEDRIVE => 'stage_id',
Configuration::PROVIDER_COPPER => 'pipeline_stage_id',
];
public static $enumTypes = [
self::TYPE_PICKLIST,
self::TYPE_NUMBER,
self::TYPE_CURRENCY,
self::TYPE_BOOLEAN,
self::TYPE_TEXT,
self::TYPE_TEXTAREA,
self::TYPE_EMAIL,
self::TYPE_PHONE,
self::TYPE_URL,
self::TYPE_DATE,
self::TYPE_TIME,
self::TYPE_DATETIME,
self::TYPE_UNSUPPORTED,
];
public static $enumObjectTypes = [
self::OBJECT_LEAD,
self::OBJECT_ACCOUNT,
self::OBJECT_CONTACT,
self::OBJECT_OPPORTUNITY,
self::OBJECT_TASK,
self::OBJECT_EVENT,
];
protected $table = 'crm_fields';
protected $fillable = [
'crm_configuration_id',
'crm_provider_id',
'object_type',
'type',
'label',
'description',
'is_selectable',
'is_mandatory',
'length',
'default_value',
'is_indexable',
'is_filterable',
'is_readonly',
];
protected $appends = [
'id_string',
];
protected $hidden = [
'uuid',
'id',
'crm_configuration_id',
];
protected function casts(): array
{
return [
'is_selectable' => 'boolean',
'is_mandatory' => 'boolean',
'is_indexable' => 'boolean',
'is_filterable' => 'boolean',
];
}
public function configuration(): BelongsTo
{
return $this->belongsTo(Configuration::class, 'crm_configuration_id');
}
public function entities(): HasMany
{
return $this->hasMany(LayoutEntity::class, 'crm_field_id');
}
public function getEntities(): Collection
{
/** @var Collection<LayoutEntity> $entities */
$entities = $this->getAttribute('entities');
return $entities;
}
public function values(): HasMany
{
return $this->hasMany(FieldValue::class, 'crm_field_id')->orderBy('sequence');
}
public function getLabel(): string
{
return $this->getAttribute('label');
}
public function getType(): string
{
return $this->getAttribute('type');
}
public function getObjectType(): string
{
/** @var string */
return $this->getAttribute('object_type');
}
public function getCrmProviderId(): string
{
/** @var string */
return $this->getAttribute('crm_provider_id');
}
public function getValues(): Collection
{
return $this->getAttribute('values');
}
public function isIndexable(): bool
{
return $this->getAttribute('is_indexable');
}
public function isFilterable(): bool
{
return $this->getAttribute('is_filterable');
}
public function getId(): int
{
/** @var int */
return $this->getAttribute('id');
}
public function hasDescription(): bool
{
return $this->getAttribute('description') !== null;
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function data()
{
return $this->hasMany(FieldData::class, 'crm_field_id');
}
public function crm(): BelongsTo
{
return $this->belongsTo(Configuration::class, 'crm_configuration_id');
}
#[Scope]
protected function indexable($query)
{
return $query->where('is_indexable', 1);
}
#[Scope]
protected function tasks($query)
{
return $query->where('object_type', self::OBJECT_TASK);
}
public function isBusinessType(): bool
{
return in_array($this->getCrmProviderId(), self::BUSINESS_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function isStageField(): bool
{
return in_array($this->getCrmProviderId(), self::STAGE_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function isPipelineField(): bool
{
return in_array($this->getCrmProviderId(), self::PIPELINE_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function getUuid(): string
{
return $this->getAttribute('id_string');
}
public function getCrmConfiguration(): Configuration
{
return $this->getAttribute('crm');
}
public function getCrmConfigurationId(): int
{
return $this->getAttribute('crm_configuration_id');
}
/**
* Currently implemented only for Opportunity fields
*/
public function isReadOnly(): bool
{
// The CRM Field metadata should always be first to be taken into consideration.
if ($this->getIsReadonly()) {
return true;
}
if ($this->getObjectType() !== self::OBJECT_OPPORTUNITY) {
return false;
}
if ($this->isPipelineField()) {
return true;
}
if ($this->getType() === Field::TYPE_UNSUPPORTED) {
return true;
}
if ($this->getCrmConfiguration()->getProviderName() === Configuration::PROVIDER_INTEGRATION_APP) {
$fieldDefinitions = new CrmFieldDefinitionsManager();
return $fieldDefinitions->isReadOnly($this->getCrmProviderId(), self::OBJECT_OPPORTUNITY);
}
return false;
}
public function isPicklist(): bool
{
return in_array($this->getType(), [self::TYPE_PICKLIST, self::TYPE_MULTIPICKLIST]);
}
public function getLength(): ?int
{
return $this->getAttribute('length');
}
public function getDefaultValue(): ?string
{
return $this->getAttribute('default_value');
}
public function setIsReadonly(int $isReadonly): void
{
$this->setAttribute('is_readonly', $isReadonly);
}
public function getIsReadonly(): bool
{
return $this->getAttribute('is_readonly') !== FieldReadonlyConstants::FIELD_IS_UPDATABLE;
}
public function getEntityName(): string
{
return ucfirst($this->getObjectType()) . '.' . $this->getCrmProviderId();
}
public function crmTemplateFields(): HasMany
{
return $this->hasMany(CrmTemplateField::class, 'crm_field_id');
}
public function playbooks(): HasMany
{
return $this->hasMany(Playbook::class, 'activity_field_id');
}
public function getPlaybooks(): Collection
{
return $this->getAttribute('playbooks');
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny...
|
79487
|
NULL
|
NULL
|
NULL
|
|
79487
|
2786
|
31
|
2026-05-28T06:31:32.797747+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949892797_m1.jpg...
|
iTerm2
|
NULL
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV (docker)₴2-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206-> origin/!ce9abde868..3800efb7ea JY-20905-tool-search-membersad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-...ED→HomeDMsActivityFilesJiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...Later...More+. Direct messages&. Petko Kashinskiã. Stefka Stoyanova: Todor StamatovSteliyan GeorgievVes% MiraP. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:32Describe what you are looking forPetko Kashinski6 0• MessagesAdd canvas@ Files+Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, нo 'MultiPicklist' type, a нe single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастихм, не сьм сигуренще проверяShift + Return to add a new line...
|
NULL
|
-2008629176138658986
|
NULL
|
typing_pause
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV (docker)₴2-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206-> origin/!ce9abde868..3800efb7ea JY-20905-tool-search-membersad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-...ED→HomeDMsActivityFilesJiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...Later...More+. Direct messages&. Petko Kashinskiã. Stefka Stoyanova: Todor StamatovSteliyan GeorgievVes% MiraP. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:32Describe what you are looking forPetko Kashinski6 0• MessagesAdd canvas@ Files+Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, нo 'MultiPicklist' type, a нe single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастихм, не сьм сигуренще проверяShift + Return to add a new line...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79486
|
2786
|
30
|
2026-05-28T06:31:28.215911+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949888215_m1.jpg...
|
iTerm2
|
NULL
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV (docker)₴2-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206-> origin/!ce9abde868..3800efb7ea JY-20905-tool-search-membersad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-...ED→HomeDMsActivityFilesJiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...Later...More+. Direct messages&. Petko Kashinskiã. Stefka Stoyanova: Todor StamatovSteliyan GeorgievVes% MiraP.. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:27Describe what you are looking forPetko Kashinski6 0• MessagesAdd canvas@ Files+Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, нo 'MultiPicklist' type, a нe single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастихм, не сьм сигуренще проверя |Shift + Return to add a new line...
|
NULL
|
-3375364909488396559
|
NULL
|
typing_pause
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV (docker)₴2-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206-> origin/!ce9abde868..3800efb7ea JY-20905-tool-search-membersad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-...ED→HomeDMsActivityFilesJiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...Later...More+. Direct messages&. Petko Kashinskiã. Stefka Stoyanova: Todor StamatovSteliyan GeorgievVes% MiraP.. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:27Describe what you are looking forPetko Kashinski6 0• MessagesAdd canvas@ Files+Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, нo 'MultiPicklist' type, a нe single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастихм, не сьм сигуренще проверя |Shift + Return to add a new line...
|
79485
|
NULL
|
NULL
|
NULL
|
|
79485
|
2786
|
29
|
2026-05-28T06:31:25.269057+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949885269_m1.jpg...
|
iTerm2
|
NULL
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV (docker)₴2-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206-> origin/!ce9abde868..3800efb7ea JY-20905-tool-search-membersad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-...ED→HomeDMsActivityFilesJiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...Later...More+. Direct messages&. Petko Kashinskiã. Stefka Stoyanova: Todor StamatovSteliyan GeorgievVes% MiraP. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:24Describe what you are looking forPetko Kashinski6 0• MessagesAdd canvas@ Files+Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, нo 'MultiPicklist' type, a нe single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастихм, не сьм сигуренще проверяShift + Return to add a new line...
|
NULL
|
914844389944420762
|
NULL
|
typing_pause
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV (docker)₴2-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206-> origin/!ce9abde868..3800efb7ea JY-20905-tool-search-membersad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-...ED→HomeDMsActivityFilesJiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...Later...More+. Direct messages&. Petko Kashinskiã. Stefka Stoyanova: Todor StamatovSteliyan GeorgievVes% MiraP. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:24Describe what you are looking forPetko Kashinski6 0• MessagesAdd canvas@ Files+Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, нo 'MultiPicklist' type, a нe single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастихм, не сьм сигуренще проверяShift + Return to add a new line...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79484
|
2786
|
28
|
2026-05-28T06:31:23.302266+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949883302_m1.jpg...
|
iTerm2
|
NULL
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV (docker)₴2-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206masterce9abde868..3800efb7ea JY-20905-tool-search-members-> origin/!origin/.ad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.php6tests/Unit/Services/Mail/TextRelayServiceTest.php1132 files changed, 14 insertions(+),5 deletions(-)lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-...ED→HomeDMsActivityFilesJiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...Later...More+. Direct messages&. Petko Kashinskião Stefka Stoyanova: Todor StamatovSteliyan GeorgievVes% MiraP.. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:22Describe what you are looking forPetko Kashinski6 0• MessagesAdd canvas@ Files+Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, нo 'MultiPicklist' type, a нe single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастихм, не сьм сигуренще..•...
|
NULL
|
6597334370527309145
|
NULL
|
typing_pause
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV (docker)₴2-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206masterce9abde868..3800efb7ea JY-20905-tool-search-members-> origin/!origin/.ad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.php6tests/Unit/Services/Mail/TextRelayServiceTest.php1132 files changed, 14 insertions(+),5 deletions(-)lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-...ED→HomeDMsActivityFilesJiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...Later...More+. Direct messages&. Petko Kashinskião Stefka Stoyanova: Todor StamatovSteliyan GeorgievVes% MiraP.. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:22Describe what you are looking forPetko Kashinski6 0• MessagesAdd canvas@ Files+Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, нo 'MultiPicklist' type, a нe single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастихм, не сьм сигуренще..•...
|
79483
|
NULL
|
NULL
|
NULL
|
|
79483
|
2786
|
27
|
2026-05-28T06:31:20.927177+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949880927_m1.jpg...
|
iTerm2
|
NULL
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV (docker)₴2-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206-> origin/!ce9abde868..3800efb7ea JY-20905-tool-search-membersad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-...ED→HomeDMsActivityFilesJiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...Later...More+. Direct messages&. Petko Kashinskião Stefka Stoyanova: Todor StamatovSteliyan GeorgievVes% MiraP. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:20Describe what you are looking forPetko Kashinski6 0• Messagest Add canvasO FilesMonuay, May 11ur+Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, но 'MultiPicklist' type, a не single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастихм, не сьм сигуренShift + Return to add a new line...
|
NULL
|
968389416786072020
|
NULL
|
typing_pause
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV (docker)₴2-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206-> origin/!ce9abde868..3800efb7ea JY-20905-tool-search-membersad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-...ED→HomeDMsActivityFilesJiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...Later...More+. Direct messages&. Petko Kashinskião Stefka Stoyanova: Todor StamatovSteliyan GeorgievVes% MiraP. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:20Describe what you are looking forPetko Kashinski6 0• Messagest Add canvasO FilesMonuay, May 11ur+Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, но 'MultiPicklist' type, a не single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастихм, не сьм сигуренShift + Return to add a new line...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79482
|
2786
|
26
|
2026-05-28T06:31:16.869532+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949876869_m1.jpg...
|
iTerm2
|
NULL
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV (docker)₴2-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206-> origin/!ce9abde868..3800efb7ea JY-20905-tool-search-membersad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-...ED→HomeDMsActivityFilesJiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...Later...More+. Direct messages&. Petko Kashinskiã. Stefka Stoyanova: Todor StamatovSteliyan GeorgievVes% MiraP. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:16Describe what you are looking forPetko Kashinski6 0• Messagest Add canvasO FilesMonuay, May 11ur+Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, но 'MultiPicklist' type, a не single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастихм, не съм сигуренShift + Return to add a new line...
|
NULL
|
-3110669243459497283
|
NULL
|
typing_pause
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV (docker)₴2-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206-> origin/!ce9abde868..3800efb7ea JY-20905-tool-search-membersad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-...ED→HomeDMsActivityFilesJiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...Later...More+. Direct messages&. Petko Kashinskiã. Stefka Stoyanova: Todor StamatovSteliyan GeorgievVes% MiraP. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:16Describe what you are looking forPetko Kashinski6 0• Messagest Add canvasO FilesMonuay, May 11ur+Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, но 'MultiPicklist' type, a не single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастихм, не съм сигуренShift + Return to add a new line...
|
79481
|
NULL
|
NULL
|
NULL
|
|
79481
|
2786
|
25
|
2026-05-28T06:31:15.062577+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949875062_m1.jpg...
|
iTerm2
|
NULL
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV (docker)₴2-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206-> origin/!ce9abde868..3800efb7ea JY-20905-tool-search-membersad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-...ED→HomeDMsActivityFilesJiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...Later...More+. Direct messages&. Petko Kashinskiã. Stefka Stoyanova: Todor StamatovSteliyan GeorgievVes% MiraP. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:14Describe what you are looking forPetko Kashinski6 0• Messagest Add canvasO FilesMonuay, May 11ur+Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, но 'MultiPicklist' type, a не single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастихм, не съм|+Shift + Return to add a new line...
|
NULL
|
3927395179940131678
|
NULL
|
typing_pause
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV (docker)₴2-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206-> origin/!ce9abde868..3800efb7ea JY-20905-tool-search-membersad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-...ED→HomeDMsActivityFilesJiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...Later...More+. Direct messages&. Petko Kashinskiã. Stefka Stoyanova: Todor StamatovSteliyan GeorgievVes% MiraP. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:14Describe what you are looking forPetko Kashinski6 0• Messagest Add canvasO FilesMonuay, May 11ur+Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, но 'MultiPicklist' type, a не single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастихм, не съм|+Shift + Return to add a new line...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79480
|
2787
|
47
|
2026-05-28T06:31:12.697874+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949872697_m2.jpg...
|
iTerm2
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
8%rnostolFv faVsco.isproidetM.CLAUDE mdcomposer.js 8%rnostolFv faVsco.isproidetM.CLAUDE mdcomposer.jsoncomooserlock0 dependency-checker.jsondew.sonF ids.txtintection.son.deMAINCTAImMEINTERNAL_WEBHOOK SETUP.mdjiminny_storageMallicaneae maM Makefile# package-lock.jsonEphostan.neon.distEphpstan-baseline.neo< phpunit.xmlMraw_sqLquery.sgM: README maệ sonar-project.propertiesEtestiov<> Untitied Diagram.xmlsvetur.confio.i>1h Extemal Librariesv Scratches and ConsolesveieostconsoltsvAEUconsole liaulADEAL RISKS (EUToNTEUAEU (EU]ylliminnusochinostV A PRODA console PRODDI (PROD"> AQA> AOAI> A QAI PRODA STAGING>M ExtensionsMScratchas©) Kernelphp© SyncMailbox.phpTextRelayServiceTest.phpPyyminny.on.env.productioclass Field extends Model87public const int NAME_MAX_LENGTH = 128;public const int LABEL_MAX_LENGTH = 255;public const int DESCRIPTION_MAX_LENGTH = 191;public const string TYPE_MULTIPICKLISI = 'nulti-picklist';I Not yet supportedTMockarihlaravel.logs-tim.anuchioesthoedXWeloesilracooesthoehconedia PereA console (STAGING)AA XA AYD000€POM activitles &IIN users u 1.nc->1: ON a.user_id = u.icJERE& console (EU)Do jminny=24425826511II— 021 A1 A18 V2 V6 Aa.status ='completedAno uurd co bind 6411800-1608-4201-8726-4757079da08eD = u.uusdAND a.deleted_at IS NULLANDSXTESAND + tune TM fiaudio! tusden!yIDER BY a.actual_start_time DESCJlort & foon toane whond id= 10.flect * fron crn configurations where provider = 'pipedrive"SISCTCONCAT(u.id, CASE WHEN u.id = t.ouner id THEN " (ouner)' ELSE ** END) AS user idv.enail,sa.*thouner1d FROM socilal accounts saJTN users u on uid = sa,sociable ioJTN teans t 1.nc-›1: on t5id = u.team idlJERE u,tean 1d = 19 and sa,oroviden = "pipedoive':SLECT * FROM social accounts WHERE 1d = 1116%DATE sochal accounte SET onowiden usen token = *VAu:AOTBAHS-L2TNK2yuuuaLo1f2hWb9ccUNKTok4F109cinXoo 6AE0h0h00Va1nvalCHEynovS)owiden nefresh token = [TELEGRAM_TOKEN]6944446h6b2bfc*)oines = 99891994JERE $d = 1116.provider_user-token": "viu:AQLBAH5-L2/NK2yuuuaLqifzh#b9crUNKtpk4F109minXap_6AE0hDhD0Va1nviCHEvnpvSEAAAAf:1888gkqhk169w8BBwueMont &tmn en old vahuoc)ilect * fron crm fields where type = 'nulti-picklist':LECT * FROM Crn_ Layouts WHERE uuid_to_bin(*7C327871-4c25-4c56-9a0f-44c5a849d65c') = uuid;Sieo& Conk eng louant onttoe Nusoeonnloudtth202"BLEOT & EOOM onn Eioldo wuGOS 3a - 20141 # 1906SISOT & SOOM AN BOTH MOTHOG NHEOS An 31O12 12 C 791/2.o ino co moy Siol.lTextRelayServiceTesteeendhner hensewiet+0.can I test it locally first. if I place env from stagingYes. The service relies on a tew thinas wou'd need in olacel1. Credentials file The constructor expects storage/text-relay.ison (a Google service account JSON key file)Gmbtrom sthaind and oince it there2. .env values to copy from stagingGOOGLE TEXTUSERECOOGLE TEXTI HASTGOOGLE TEXT RELAY TOPIC:DEPLOY REGION:the cnail mailbox address# e.g. txt.jiminny.com or txt.staging.jiminny.com# the Pub/Sub topic namaeu or us3. Run the sunc manualiv vin tinker tinside docker 1aeo 1%b bashaegdocker exec -it docker_lamp_1 php artisan tinkeapp(\Jiminny\Services\Ma1l\TextRelayService::class)-sync():Caveat: The service reads from Gmail history and dispatches jobs to the queue. If you don't want it to actuallsend SMS, make sure QUEUE_CONNECTICN»sync is not set (or use a test queue), or just call isForCurrentEnvironntioh.Ssvc = new class extends \Jiminny\Services\Mail\TextRelayService & public function _construct(Som Service ssvc-soctServicelcont.aasI then sinsoect aueessaaesasg= sonailService-susers_messages-sget(config(*iminty.google text user'), *THE_MESSAGE ID')collect(5-s0-20etPayload()-soetWeaders())-soluck("value"thut wey von can Mrit whht nandore tra nenhily oraeaet do htas macesod Calora tha ull evoc nineGadl -public const array STAGE_TYPE_FIELDS = [tontsaunst onponvinse sasesten g iwhoslseaAck amthine (oLCAhantiv...
|
NULL
|
-8926161993726960953
|
NULL
|
typing_pause
|
ocr
|
NULL
|
8%rnostolFv faVsco.isproidetM.CLAUDE mdcomposer.js 8%rnostolFv faVsco.isproidetM.CLAUDE mdcomposer.jsoncomooserlock0 dependency-checker.jsondew.sonF ids.txtintection.son.deMAINCTAImMEINTERNAL_WEBHOOK SETUP.mdjiminny_storageMallicaneae maM Makefile# package-lock.jsonEphostan.neon.distEphpstan-baseline.neo< phpunit.xmlMraw_sqLquery.sgM: README maệ sonar-project.propertiesEtestiov<> Untitied Diagram.xmlsvetur.confio.i>1h Extemal Librariesv Scratches and ConsolesveieostconsoltsvAEUconsole liaulADEAL RISKS (EUToNTEUAEU (EU]ylliminnusochinostV A PRODA console PRODDI (PROD"> AQA> AOAI> A QAI PRODA STAGING>M ExtensionsMScratchas©) Kernelphp© SyncMailbox.phpTextRelayServiceTest.phpPyyminny.on.env.productioclass Field extends Model87public const int NAME_MAX_LENGTH = 128;public const int LABEL_MAX_LENGTH = 255;public const int DESCRIPTION_MAX_LENGTH = 191;public const string TYPE_MULTIPICKLISI = 'nulti-picklist';I Not yet supportedTMockarihlaravel.logs-tim.anuchioesthoedXWeloesilracooesthoehconedia PereA console (STAGING)AA XA AYD000€POM activitles &IIN users u 1.nc->1: ON a.user_id = u.icJERE& console (EU)Do jminny=24425826511II— 021 A1 A18 V2 V6 Aa.status ='completedAno uurd co bind 6411800-1608-4201-8726-4757079da08eD = u.uusdAND a.deleted_at IS NULLANDSXTESAND + tune TM fiaudio! tusden!yIDER BY a.actual_start_time DESCJlort & foon toane whond id= 10.flect * fron crn configurations where provider = 'pipedrive"SISCTCONCAT(u.id, CASE WHEN u.id = t.ouner id THEN " (ouner)' ELSE ** END) AS user idv.enail,sa.*thouner1d FROM socilal accounts saJTN users u on uid = sa,sociable ioJTN teans t 1.nc-›1: on t5id = u.team idlJERE u,tean 1d = 19 and sa,oroviden = "pipedoive':SLECT * FROM social accounts WHERE 1d = 1116%DATE sochal accounte SET onowiden usen token = *VAu:AOTBAHS-L2TNK2yuuuaLo1f2hWb9ccUNKTok4F109cinXoo 6AE0h0h00Va1nvalCHEynovS)owiden nefresh token = [TELEGRAM_TOKEN]6944446h6b2bfc*)oines = 99891994JERE $d = 1116.provider_user-token": "viu:AQLBAH5-L2/NK2yuuuaLqifzh#b9crUNKtpk4F109minXap_6AE0hDhD0Va1nviCHEvnpvSEAAAAf:1888gkqhk169w8BBwueMont &tmn en old vahuoc)ilect * fron crm fields where type = 'nulti-picklist':LECT * FROM Crn_ Layouts WHERE uuid_to_bin(*7C327871-4c25-4c56-9a0f-44c5a849d65c') = uuid;Sieo& Conk eng louant onttoe Nusoeonnloudtth202"BLEOT & EOOM onn Eioldo wuGOS 3a - 20141 # 1906SISOT & SOOM AN BOTH MOTHOG NHEOS An 31O12 12 C 791/2.o ino co moy Siol.lTextRelayServiceTesteeendhner hensewiet+0.can I test it locally first. if I place env from stagingYes. The service relies on a tew thinas wou'd need in olacel1. Credentials file The constructor expects storage/text-relay.ison (a Google service account JSON key file)Gmbtrom sthaind and oince it there2. .env values to copy from stagingGOOGLE TEXTUSERECOOGLE TEXTI HASTGOOGLE TEXT RELAY TOPIC:DEPLOY REGION:the cnail mailbox address# e.g. txt.jiminny.com or txt.staging.jiminny.com# the Pub/Sub topic namaeu or us3. Run the sunc manualiv vin tinker tinside docker 1aeo 1%b bashaegdocker exec -it docker_lamp_1 php artisan tinkeapp(\Jiminny\Services\Ma1l\TextRelayService::class)-sync():Caveat: The service reads from Gmail history and dispatches jobs to the queue. If you don't want it to actuallsend SMS, make sure QUEUE_CONNECTICN»sync is not set (or use a test queue), or just call isForCurrentEnvironntioh.Ssvc = new class extends \Jiminny\Services\Mail\TextRelayService & public function _construct(Som Service ssvc-soctServicelcont.aasI then sinsoect aueessaaesasg= sonailService-susers_messages-sget(config(*iminty.google text user'), *THE_MESSAGE ID')collect(5-s0-20etPayload()-soetWeaders())-soluck("value"thut wey von can Mrit whht nandore tra nenhily oraeaet do htas macesod Calora tha ull evoc nineGadl -public const array STAGE_TYPE_FIELDS = [tontsaunst onponvinse sasesten g iwhoslseaAck amthine (oLCAhantiv...
|
79478
|
NULL
|
NULL
|
NULL
|
|
79479
|
2786
|
24
|
2026-05-28T06:31:12.597446+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949872597_m1.jpg...
|
iTerm2
|
NULL
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV (docker)₴2-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206-> origin/!ce9abde868..3800efb7ea JY-20905-tool-search-membersad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-...ED→HomeDMsActivityFilesJiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...Later...More+. Direct messages&. Petko Kashinskião Stefka Stoyanova: Todor StamatovSteliyan GeorgievVes% MiraP. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:12Describe what you are looking forPetko Kashinski6 0• Messagest Add canvasO FilesMonuay, May 11ur+Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, но 'MultiPicklist' type, a не single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастиXM+Аа..•...
|
NULL
|
-5407848861331805699
|
NULL
|
typing_pause
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER*81DEV (docker)₴2-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206-> origin/!ce9abde868..3800efb7ea JY-20905-tool-search-membersad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-...ED→HomeDMsActivityFilesJiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...Later...More+. Direct messages&. Petko Kashinskião Stefka Stoyanova: Todor StamatovSteliyan GeorgievVes% MiraP. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:12Describe what you are looking forPetko Kashinski6 0• Messagest Add canvasO FilesMonuay, May 11ur+Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, но 'MultiPicklist' type, a не single. 3а Single знам, че може.Lukas Kovalik 9:31 AMздрастиXM+Аа..•...
|
79477
|
NULL
|
NULL
|
NULL
|
|
79478
|
2787
|
46
|
2026-05-28T06:31:10.643393+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949870643_m2.jpg...
|
iTerm2
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
8%rnostolFv faVsco.isproidetM.CLAUDE mdcomposer.js 8%rnostolFv faVsco.isproidetM.CLAUDE mdcomposer.jsoncomooserlock0 dependency-checker.jsondew.sonF ids.txtintection.son.deMAINCTAImMEINTERNAL_WEBHOOK SETUP.mdjiminny_storageMallicaneae maM Makefile# package-lock.jsonEphostan.neon.distEphpstan-baseline.neo< phpunit.xmlMraw_sqLquery.sgM: README maệ sonar-project.propertiesEtestiov<> Untitied Diagram.xmlsvetur.confio.i>1h Extemal Librariesv Scratches and ConsolesveieostconsoltsvAEUA console fEulADEAL RISKS (EUNoNTEUAEU (EU]ylliminnusochinostV A PRODA console PRODDI (PROD"> AQA> AOAI> A QAI PRODA STAGING>M ExtensionsMScratchas©) Kernelphp© SyncMailbox.phpTextRelayServiceTest.phpPyyminny.on.env.productioclass Field extends Model87public const int NAME_MAX_LENGTH = 128;public const int LABEL_MAX_LENGTH = 255;public const int DESCRIPTION_MAX_LENGTH = 191;public const string TYPE_MULTIPICKLISI = 'nulti-picklist';I Not yet supportedTMockarihlaravel.logs-tim.anuchioesthoedXWeloesilracooesthoehconedia PereA console (STAGING)AA XA AYD000€POM activitales &IIN users u 1.nc->1: ON a.user_id = u.icJERE& console (EU)Do jminny=24425826511II— 021 A1 A18 V2 V6 Aa.status ='completedAno uurd co bind 6411800-1608-4201-8726-4757079da08eD = u.uusdAND a.deleted_at IS NULLANDSXTESAND + tune TM fiaudio! tusden!yIDER BY a.actual_start_time DESCJlort & foon toane whond id= 10.flect * fron crn configurations where provider = 'pipedrive"SISCTCONCAT(u.id, CASE WHEN u.id = t.ouner id THEN " (ouner)' ELSE ** END) AS user idv.enail,sa.*thouner1d FROM socilal accounts saJTN users u on uid = sa,sociable ioJTN teans t 1.nc-›1: on t5id = u.team idlJERE u,tean 1d = 19 and sa,oroviden = "pipedoive':SLECT * FROM social accounts WHERE 1d = 1116%DATE sochal accounte SET onowiden usen token = *VAu:AOTBAHS-L2TNK2yuuuaLo1f2hWb9ccUNKTok4F109cinXoo 6AE0h0h00Va1nvalCHEynovS)owiden nefresh token = [TELEGRAM_TOKEN]6944446h6b2bfc*)oines = 99891994JERE $d = 1116.provider_user-token": "viu:AQLBAH5-L2/NK2yuuuaLqifzh#b9crUNKtpk4F109minXap_6AE0hDhD0Va1nviCHEvnpvSEAAAAf:1888gkqhk169w8BBwueMont &tmn en old vahuoc)ilect * fron crm fields where type = 'nulti-picklist':LECT * FROM Crn_ Layouts WHERE uuid_to_bin(*7C327871-4c25-4c56-9a0f-44c5a849d65c') = uuid;Sieo& Conk eng louant onttoe Nusoeonnloudtth202"BLEOT & EOOM onn Eioldo wuGOS 3a - 20141 # 1906SISOT & SOOM AN BOTH MOTHOG NHEOS An 31O12 12 C 791/2.ao Inu co moy Siol.luTextRelayServiceTesteeendhner hensewiet+0.can I test it locally first. if I place env from stagingYes. The service relies on a tew thinas wou'd need in olacel1. Credentials file The constructor expects storage/text-relay.ison (a Google service account JSON key file)Gmbtrom sthaind and oince it there2. .env values to copy from stagingGOOGLE TEXTUSERECOOGLE TEXTI HASTGOOGLE TEXT RELAY TOPIC:DEPLOY REGION:the cnail mailbox address# e.g. txt.jiminny.com or txt.staging.jiminny.com# the Pub/Sub topic namaeu or us3. Run the sunc manualiv vin tinker tinside docker 1aeo 1%b bashaegdocker exec -it docker_lamp_1 php artisan tinkeapp(\Jiminny\Services\Ma1l\TextRelayService::class)-sync():Caveat: The service reads from Gmail history and dispatches jobs to the queue. If you don't want it to actuallsend SMS, make sure QUEUE_CONNECTICN»sync is not set (or use a test queue), or just call isForCurrentEnvironntioh.Ssvc = new class extends \Jiminny\Services\Mail\TextRelayService & public function _construct(Som Service ssvc-soctServicelcont.aasI then sinsoect aueessaaesasg= sonailService-susers_messages-sget(config(*iminty.google text user'), *THE_MESSAGE ID')collect(5-s0-20etPayload()-soetWeaders())-soluck("value"thut wey von can Mrit whht nandore tra nenhily oraeaet do htas macesod Calora tha ull evoc nineGadl -public const array STAGE_TYPE_FIELDS = [tontsaunst onponvinse sasesten g iwhoslseaAck amthine (oLCAhantiv...
|
NULL
|
3364239530535476107
|
NULL
|
typing_pause
|
ocr
|
NULL
|
8%rnostolFv faVsco.isproidetM.CLAUDE mdcomposer.js 8%rnostolFv faVsco.isproidetM.CLAUDE mdcomposer.jsoncomooserlock0 dependency-checker.jsondew.sonF ids.txtintection.son.deMAINCTAImMEINTERNAL_WEBHOOK SETUP.mdjiminny_storageMallicaneae maM Makefile# package-lock.jsonEphostan.neon.distEphpstan-baseline.neo< phpunit.xmlMraw_sqLquery.sgM: README maệ sonar-project.propertiesEtestiov<> Untitied Diagram.xmlsvetur.confio.i>1h Extemal Librariesv Scratches and ConsolesveieostconsoltsvAEUA console fEulADEAL RISKS (EUNoNTEUAEU (EU]ylliminnusochinostV A PRODA console PRODDI (PROD"> AQA> AOAI> A QAI PRODA STAGING>M ExtensionsMScratchas©) Kernelphp© SyncMailbox.phpTextRelayServiceTest.phpPyyminny.on.env.productioclass Field extends Model87public const int NAME_MAX_LENGTH = 128;public const int LABEL_MAX_LENGTH = 255;public const int DESCRIPTION_MAX_LENGTH = 191;public const string TYPE_MULTIPICKLISI = 'nulti-picklist';I Not yet supportedTMockarihlaravel.logs-tim.anuchioesthoedXWeloesilracooesthoehconedia PereA console (STAGING)AA XA AYD000€POM activitales &IIN users u 1.nc->1: ON a.user_id = u.icJERE& console (EU)Do jminny=24425826511II— 021 A1 A18 V2 V6 Aa.status ='completedAno uurd co bind 6411800-1608-4201-8726-4757079da08eD = u.uusdAND a.deleted_at IS NULLANDSXTESAND + tune TM fiaudio! tusden!yIDER BY a.actual_start_time DESCJlort & foon toane whond id= 10.flect * fron crn configurations where provider = 'pipedrive"SISCTCONCAT(u.id, CASE WHEN u.id = t.ouner id THEN " (ouner)' ELSE ** END) AS user idv.enail,sa.*thouner1d FROM socilal accounts saJTN users u on uid = sa,sociable ioJTN teans t 1.nc-›1: on t5id = u.team idlJERE u,tean 1d = 19 and sa,oroviden = "pipedoive':SLECT * FROM social accounts WHERE 1d = 1116%DATE sochal accounte SET onowiden usen token = *VAu:AOTBAHS-L2TNK2yuuuaLo1f2hWb9ccUNKTok4F109cinXoo 6AE0h0h00Va1nvalCHEynovS)owiden nefresh token = [TELEGRAM_TOKEN]6944446h6b2bfc*)oines = 99891994JERE $d = 1116.provider_user-token": "viu:AQLBAH5-L2/NK2yuuuaLqifzh#b9crUNKtpk4F109minXap_6AE0hDhD0Va1nviCHEvnpvSEAAAAf:1888gkqhk169w8BBwueMont &tmn en old vahuoc)ilect * fron crm fields where type = 'nulti-picklist':LECT * FROM Crn_ Layouts WHERE uuid_to_bin(*7C327871-4c25-4c56-9a0f-44c5a849d65c') = uuid;Sieo& Conk eng louant onttoe Nusoeonnloudtth202"BLEOT & EOOM onn Eioldo wuGOS 3a - 20141 # 1906SISOT & SOOM AN BOTH MOTHOG NHEOS An 31O12 12 C 791/2.ao Inu co moy Siol.luTextRelayServiceTesteeendhner hensewiet+0.can I test it locally first. if I place env from stagingYes. The service relies on a tew thinas wou'd need in olacel1. Credentials file The constructor expects storage/text-relay.ison (a Google service account JSON key file)Gmbtrom sthaind and oince it there2. .env values to copy from stagingGOOGLE TEXTUSERECOOGLE TEXTI HASTGOOGLE TEXT RELAY TOPIC:DEPLOY REGION:the cnail mailbox address# e.g. txt.jiminny.com or txt.staging.jiminny.com# the Pub/Sub topic namaeu or us3. Run the sunc manualiv vin tinker tinside docker 1aeo 1%b bashaegdocker exec -it docker_lamp_1 php artisan tinkeapp(\Jiminny\Services\Ma1l\TextRelayService::class)-sync():Caveat: The service reads from Gmail history and dispatches jobs to the queue. If you don't want it to actuallsend SMS, make sure QUEUE_CONNECTICN»sync is not set (or use a test queue), or just call isForCurrentEnvironntioh.Ssvc = new class extends \Jiminny\Services\Mail\TextRelayService & public function _construct(Som Service ssvc-soctServicelcont.aasI then sinsoect aueessaaesasg= sonailService-susers_messages-sget(config(*iminty.google text user'), *THE_MESSAGE ID')collect(5-s0-20etPayload()-soetWeaders())-soluck("value"thut wey von can Mrit whht nandore tra nenhily oraeaet do htas macesod Calora tha ull evoc nineGadl -public const array STAGE_TYPE_FIELDS = [tontsaunst onponvinse sasesten g iwhoslseaAck amthine (oLCAhantiv...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79477
|
2786
|
23
|
2026-05-28T06:31:09.471720+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949869471_m1.jpg...
|
iTerm2
|
NULL
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV (docker)₴2...ED-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206ce9abde868..3800efb7ea JY-20905-tool-search-members-> origin/!origin/.ad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-HomeDMsActivityFilesLater...More+→Jiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi.... Direct messages&. Stefka Stoyanova& Petko Kashinski: Todor StamatovSteliyan GeorgievVes% MiraP.. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:09Describe what you are looking forPetko Kashinski6 0MessagesAdd canvasO Files+Petko KastplaybackVisitedMonday, May 11th ~Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, но 'MultiPicklist' type, a не single. 3а Single знам, че може.здрастиShift + Return to add a new line...
|
NULL
|
-3714528068001571672
|
NULL
|
typing_pause
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV (docker)₴2...ED-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206ce9abde868..3800efb7ea JY-20905-tool-search-members-> origin/!origin/.ad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-HomeDMsActivityFilesLater...More+→Jiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi.... Direct messages&. Stefka Stoyanova& Petko Kashinski: Todor StamatovSteliyan GeorgievVes% MiraP.. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:09Describe what you are looking forPetko Kashinski6 0MessagesAdd canvasO Files+Petko KastplaybackVisitedMonday, May 11th ~Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, но 'MultiPicklist' type, a не single. 3а Single знам, че може.здрастиShift + Return to add a new line...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79476
|
2787
|
45
|
2026-05-28T06:31:09.368402+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949869368_m2.jpg...
|
iTerm2
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
8%rnostolFv faVsco.isproidetM.CLAUDE mdcomposer.js 8%rnostolFv faVsco.isproidetM.CLAUDE mdcomposer.jsoncomooserlock0 dependency-checker.jsondew.sonF ids.txtintection.son.deMAINCTAImMAINSeNAws.wowcsnemjiminny_storageMallicaneae maM Makefile# package-lock.jsonEphostan.neon.distEphpstan-baseline.neo< phpunit.xmlMraw_sqLquery.sgM: README maệ sonar-project.propertiesEtestiov<> Untitied Diagram.xmlsvetur.confio.i>1h Extemal Librariesv Scratches and ConsolesYteeostConotvAEUA console fEulADEAL RISKS (EUNoNTEUAEU (EU]ylliminnusochinostV A PRODA console PRODDI (PROD"> AQA> AOAI> A QAI PRODASTAGING>M ExtensionsMScratchas©) Kernelphp© SyncMailbox.phpTextRelayServiceTest.phpPyyminny.on.env.productioclass Field extends Model87public const int NAME_MAX_LENGTH = 128;public const int LABEL_MAX_LENGTH = 255;public const int DESCRIPTION_MAX_LENGTH = 191;public const string TYPE_MULTIPICKLIST = 'nulti-picklist';I Not yet supportedTMockarihlaravel.logs-tim.anuchioesthoedXWeloesilracooesthoehconedia PereA console (STAGING)AA XA AYD000€POM activitales &IIN users u 1.nc->1: ON a.user_id = u.icJERE& console (EU)Do jminny=24425826511II— 021 A1 A18 V2 V6 Aa.status ='completedAno uurd co bind 6411800-1608-4201-8726-4757079da08eD = u.uusdAND a.deleted_at IS NULLANDSXTESAND + tune TM fiaudio! tusden!yIDER BY a.actual_start_time DESCJlort & foon toane whond id= 10.flect * fron crn configurations where provider = 'pipedrive"SISCTCONCAT(u.id, CASE WHEN u.id = t.ouner id THEN " (ouner)' ELSE ** END) AS user idv.enail,sa.*thouner1d FROM socilal accounts saJTN users u on uid = sa,sociable ioJTN teans t 1.nc-›1: on t5id = u.team idlJERE u,tean s1d = 19 and sa,prowider = "pioedoive":SLECT * FROM social accounts WHERE 1d = 1116%DATE sochal accounte SET onowiden usen token = *VAu:AOTBAHS-L2TNK2yuuuaLo1f2hWb9ccUNKTok4F109cinXoo 6AE0h0h00Va1nvalCHEynovS)owiden nefresh token = [TELEGRAM_TOKEN]6944446h6b2bfc*)oines = 99891994JERE $d = 1116.provider_user-token": "viu:AQLBAH5-L2/NK2yuuuaLqifzh#b9crUNKtpk4F109minXap_6AE0hDhD0Va1nviCHEvnpvSEAAAAf:1888gkqhk169w8BBwueMont &tmn en old vahuoc)ilect * fron crm fields where type = 'nulti-picklist':LECT * FROM Crn_ Layouts WHERE uuid_to_bin(*7C327871-4c25-4c56-9a0f-44c5a849d65c') = uuid;Sieo& Conk eng louant onttoe Nusoeonnloudtth202"BLEOT & EOOM onn Eioldo wuGOS 3a - 20141 # 1906SISOT & SOOM AN BOTH MOTHOG NHEOS An 31O12 12 C 791/2.ao inu co moy Siol.UaTextRelayServiceTesteeendhner hensewiet+0.can I test it locally first. if I place env from stagingYes. The service relies on a tew thinas wou'd need in olacel1. Credentials file The constructor expects storage/text-relay.ison (a Google service account JSON key file)Gmbtrom sthaind and oince it there2. .env values to copy from stagingGOOGLE TEXTUSERECOOGLE TEXT HASTGOOGLE TEXT RELAY TOPIC:DEPLOY REGION:the cnail mailbox address# e.g. txt.jiminny.com or txt.staging.jiminny.com# the Pub/Sub topic namaeu or us3. Run the sunc manualiv vin tinker tinside docker 1aeo 1%b bashaegdocker exec -it docker_lamp_1 php artisan tinkeapp(\Jiminny\Services\Ma1l\TextRelayService::class)-sync():Caveat: The service reads from Gmail history and dispatches jobs to the queue. If you don't want it to actuallsend SMS, make sure QUEUE_CONNECTICN»sync is not set (or use a test queue), or just call isForCurrentEnvironntioh.Ssvc = new class extends \Jiminny\Services\Mail\TextRelayService & public function _construct(Som Service ssvc-soctServicelcont.aasI then sinsoect aueessaaesasg= sonailService-susers_messages-sget(config(*iminty.google text user'), *THE_MESSAGE ID')collect(5-s0-20etPayload()-soetWeaders())-soluck("value"thut wey von can Mrit whht nandore tra nenhily oraeaet do htas macesod Calora tha ull evoc nineGadl -public const array STAGE_TYPE_FIELDS = [tontsaunst onponvinse sasesten g iwhoslseaAck amthine (oLCAhantiv...
|
NULL
|
466762415574262160
|
NULL
|
typing_pause
|
ocr
|
NULL
|
8%rnostolFv faVsco.isproidetM.CLAUDE mdcomposer.js 8%rnostolFv faVsco.isproidetM.CLAUDE mdcomposer.jsoncomooserlock0 dependency-checker.jsondew.sonF ids.txtintection.son.deMAINCTAImMAINSeNAws.wowcsnemjiminny_storageMallicaneae maM Makefile# package-lock.jsonEphostan.neon.distEphpstan-baseline.neo< phpunit.xmlMraw_sqLquery.sgM: README maệ sonar-project.propertiesEtestiov<> Untitied Diagram.xmlsvetur.confio.i>1h Extemal Librariesv Scratches and ConsolesYteeostConotvAEUA console fEulADEAL RISKS (EUNoNTEUAEU (EU]ylliminnusochinostV A PRODA console PRODDI (PROD"> AQA> AOAI> A QAI PRODASTAGING>M ExtensionsMScratchas©) Kernelphp© SyncMailbox.phpTextRelayServiceTest.phpPyyminny.on.env.productioclass Field extends Model87public const int NAME_MAX_LENGTH = 128;public const int LABEL_MAX_LENGTH = 255;public const int DESCRIPTION_MAX_LENGTH = 191;public const string TYPE_MULTIPICKLIST = 'nulti-picklist';I Not yet supportedTMockarihlaravel.logs-tim.anuchioesthoedXWeloesilracooesthoehconedia PereA console (STAGING)AA XA AYD000€POM activitales &IIN users u 1.nc->1: ON a.user_id = u.icJERE& console (EU)Do jminny=24425826511II— 021 A1 A18 V2 V6 Aa.status ='completedAno uurd co bind 6411800-1608-4201-8726-4757079da08eD = u.uusdAND a.deleted_at IS NULLANDSXTESAND + tune TM fiaudio! tusden!yIDER BY a.actual_start_time DESCJlort & foon toane whond id= 10.flect * fron crn configurations where provider = 'pipedrive"SISCTCONCAT(u.id, CASE WHEN u.id = t.ouner id THEN " (ouner)' ELSE ** END) AS user idv.enail,sa.*thouner1d FROM socilal accounts saJTN users u on uid = sa,sociable ioJTN teans t 1.nc-›1: on t5id = u.team idlJERE u,tean s1d = 19 and sa,prowider = "pioedoive":SLECT * FROM social accounts WHERE 1d = 1116%DATE sochal accounte SET onowiden usen token = *VAu:AOTBAHS-L2TNK2yuuuaLo1f2hWb9ccUNKTok4F109cinXoo 6AE0h0h00Va1nvalCHEynovS)owiden nefresh token = [TELEGRAM_TOKEN]6944446h6b2bfc*)oines = 99891994JERE $d = 1116.provider_user-token": "viu:AQLBAH5-L2/NK2yuuuaLqifzh#b9crUNKtpk4F109minXap_6AE0hDhD0Va1nviCHEvnpvSEAAAAf:1888gkqhk169w8BBwueMont &tmn en old vahuoc)ilect * fron crm fields where type = 'nulti-picklist':LECT * FROM Crn_ Layouts WHERE uuid_to_bin(*7C327871-4c25-4c56-9a0f-44c5a849d65c') = uuid;Sieo& Conk eng louant onttoe Nusoeonnloudtth202"BLEOT & EOOM onn Eioldo wuGOS 3a - 20141 # 1906SISOT & SOOM AN BOTH MOTHOG NHEOS An 31O12 12 C 791/2.ao inu co moy Siol.UaTextRelayServiceTesteeendhner hensewiet+0.can I test it locally first. if I place env from stagingYes. The service relies on a tew thinas wou'd need in olacel1. Credentials file The constructor expects storage/text-relay.ison (a Google service account JSON key file)Gmbtrom sthaind and oince it there2. .env values to copy from stagingGOOGLE TEXTUSERECOOGLE TEXT HASTGOOGLE TEXT RELAY TOPIC:DEPLOY REGION:the cnail mailbox address# e.g. txt.jiminny.com or txt.staging.jiminny.com# the Pub/Sub topic namaeu or us3. Run the sunc manualiv vin tinker tinside docker 1aeo 1%b bashaegdocker exec -it docker_lamp_1 php artisan tinkeapp(\Jiminny\Services\Ma1l\TextRelayService::class)-sync():Caveat: The service reads from Gmail history and dispatches jobs to the queue. If you don't want it to actuallsend SMS, make sure QUEUE_CONNECTICN»sync is not set (or use a test queue), or just call isForCurrentEnvironntioh.Ssvc = new class extends \Jiminny\Services\Mail\TextRelayService & public function _construct(Som Service ssvc-soctServicelcont.aasI then sinsoect aueessaaesasg= sonailService-susers_messages-sget(config(*iminty.google text user'), *THE_MESSAGE ID')collect(5-s0-20etPayload()-soetWeaders())-soluck("value"thut wey von can Mrit whht nandore tra nenhily oraeaet do htas macesod Calora tha ull evoc nineGadl -public const array STAGE_TYPE_FIELDS = [tontsaunst onponvinse sasesten g iwhoslseaAck amthine (oLCAhantiv...
|
79474
|
NULL
|
NULL
|
NULL
|
|
79475
|
2786
|
22
|
2026-05-28T06:31:06.639792+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949866639_m1.jpg...
|
iTerm2
|
NULL
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV (docker)₴2-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206ce9abde868..3800efb7ea JY-20905-tool-search-members-> origin/iorigin/.ad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-•••EDHomeDMsActivityFilesLaterMore+→Jiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...° Direct messages&. Stefka Stoyanova& Petko Kashinski:Todor StamatovSteliyan GeorgievVes% MiraP. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:06Describe what you are looking forPetko Kashinski6 0• MessagesAdd canvasO Files+Petko KastplaybackVisitedMonday, May 11th ~Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, но 'MultiPicklist' type, a не single. 3а Single знам, че може.Message Petko Kashinski......
|
NULL
|
-3960370490051008673
|
NULL
|
visual_change
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV (docker)₴2-zshscreenpipeFixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated. Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration" is deprecated.Use "@PHP8x0Migration"instead.Rule set"@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration"instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration"instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-M.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,remote: Countingobjects: 100% (97/97),remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206ce9abde868..3800efb7ea JY-20905-tool-search-members-> origin/iorigin/.ad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/.Updating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.phptests/Unit/Services/Mail/TextRelayServiceTest.php2 files changed, 14 insertions(+),lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-miss'Switched to a new branch 'JY-20915-fix-missing-header-text-relay'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-•••EDHomeDMsActivityFilesLaterMore+→Jiminny ...# engineering# general# happy_birthday# jbu-team-info# jiminny-bg# platform-tickets# product_launches# random# releases# support# thank-yous# the_people_of_jimi...° Direct messages&. Stefka Stoyanova& Petko Kashinski:Todor StamatovSteliyan GeorgievVes% MiraP. Nikolay Yankov. Stoyan TomovP. Galya Dimitrovado James GrahamLukas Kovalik y...::: Appsã Jira CloudToast100% <478•Thu 28 May 9:31:06Describe what you are looking forPetko Kashinski6 0• MessagesAdd canvasO Files+Petko KastplaybackVisitedMonday, May 11th ~Tuesday, May 12th ~Lukas Kovalik 10:36 AMдобро утроПетко имаш ли минутка да те питам за РНPetko Kashinski 10:52 AMХей ЛукашСлед минутка окей ли е ?Lukas Kovalik 10:52 AMразбира сеPetko Kashinski 10:54 AMRdyHuddle ?A huddle happened 10:55 AMYou and Petko Kashinski were in the huddle for3m.Today ~Petko Kashinski 9:00 AMДобро утро, Лукаш. Бърз въпрос - можем ли даexpose 'Call outcome' field в Sidekick, но 'MultiPicklist' type, a не single. 3а Single знам, че може.Message Petko Kashinski......
|
79472
|
NULL
|
NULL
|
NULL
|
|
79474
|
2787
|
44
|
2026-05-28T06:31:06.149296+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949866149_m2.jpg...
|
iTerm2
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormCoocRurTool:WindowFV faVsco.|s ~$2 JY-2091 PhpStormCoocRurTool:WindowFV faVsco.|s ~$2 JY-20915-fix-mProinet vKerodloh© SyncMailbox.phpTMockarihM.CLAUDE mdlorkokyoemcelestonPyyminny.on3.env.productioncomposer.jsoncomooser ockclass Field extends Modeldependency-checker..somdew.sonF ids.txtintection.son.deMAINCTAIm85MAINSeNAws.wowcsnemjiminny_storageMallicaneae maM Makefile# package-lock.jsonphpstan.neon.distEphpstan-baseline.neo< phpunit.xmlraw-sal-query.saM: README ma& sonar-prolect.propertiesEtestiov<> Untitied Diagram.xmlas vetur.confiaieM.WEBHOOK_FILTERING.IMPLEMENTAT>1h Extemal Librariesv Scratches and ConsolesYteeostConotV AEUconsole auADEAL RISKS (EUToNTEUAEU (EU]ylliminnusochinostconsole tliminnweioch mosh#DI [EMAIL] fiminny@localhost)# SF (iminny@localhost)zoho-dev (iminny@localhost)V A PRODA console PROD# console 1 PRODADI (PROD'> AQA> AOAI>A QAI PRODV ASTAGINGA console (STAGING)111A uranus (STAGING)>M ExtensionsMScratchas123public const int NAME_MAX_LENGTH = 128:public const int LABEL_MAX_LENGTH = 255;public const int DESCRIPTION MAX LENGTH = 191:public const string TYPE_MULTIPICKLISI = 'nulti-picklist';Not yet supportedoublic const string TYPE_PERCENToublic const string TYPE_PICKLISTTYPE_NUMBERpublic const string TYPE_CURRENCYTYPE BOOLEANpublic const string TYPE_TEXTTYPE TEXTAREAqub sic const string tpE ErATqub sic const strind tNpe Uelmhe conet etaineivps luSibetetsne tuneunnonte.tpublic const string OBJECT_CALL• 'call':public const array STAGE_TYPE_FIELDS = [tontaunst on penvnse Sasesten ss iwtsoslseadThe Hunspell plugin has been deprecated. if you're not writing in Hungarian, you can safely uninstall Hunspell without affecting the dictionaries for other languages. (yesterday 15:44)laravel.logA console (STAGING)AA XA AYD000€POM activitales &IIN users u 1.nc->1: ON a.user_id = u.icJEREconedia eere& console (EU)Do jminny=24425826226326411II021 A1 A18 V2 Y6 Aa.status ='completedAno uurd to binc 64f1ac0-1608-4201-87126-075y079da08e=u.uusdAND a.deleted_at IS NULLANDSXTESAND + tune TM fiaudio! tusden!yIDER BY a.actual_start_time DESCJlort & foon toane whono id= 19.flect * fron crn configurations where provider = 'pipedrive"SISCTCONCAT(u.id, CASE WHEN u.id = t.ouner id THEN " (ouner)' ELSE ** END) AS user idv.enail,sa.*thouner1d FROM socilal accounts saJTN users u on uid = sa,sociable ioJTN teans t 1.nc-›1: on t5id = u.team idlJERE u,tean 1d = 19 and sa,oroviden = "pipedoive':SLECT * FROM social accounts WHERE 1d = 1116%DATE sochal accounte SET onowiden usen token = *VAu:AOTBAHS-L2TNK2yuuuaLo1f2hWb9ccUNKTok4F109cinXoo 6AE0h0h00Va1nvaCHEynovS)owiden nefresh token = [TELEGRAM_TOKEN]6944446h6b2bfc*)oines = 99891994JERE $d = 1116.provider_user-token": "viu:AQLBAH5-L2/NK2yuuuaLqifzh#b9crUNKtpk4F109minXap_6AE0hDhD0Va1nviiCHEvnpvSEAAAAf:1888gkqhk169w8BBwue779891992Mont &tmn en old vahuoc)ilect * fron crm fields where type = 'nulti-picklist':LECT * FROM Crn_ Layouts WHERE uuid_to_bin(*7C327871-4c25-4c56-9a0f-44c5a849d65c') = uuid;Sieo& Conken lewait onttoe nusoeonnloudtth202"BLEOT & EOOM onn Eioldo wuGOS 3a - 70141 # 1906SISOT & SOOM AN BOTH MOTHOG NHEOS An 31O12 12 C 791/2.TO0%L7Thu 28 May 9:31:05TextRelayServiceTestaer henseict+0.can I test it locally first. if I place env from stagingYes. The service relies on a tew thinas vou'd need in place1. Credentials file The constructor expects storage/text-relay.json (a Google service account JSON key file)Gmbtrom sthaind and oince it there2. .env values to copy from stagingGOOGLE TEXTUSERECOOGLE TEXTI HASTGOOGLE TEXT RELAY TOPIC:DEPLOY REGION:the cnail mailbox address# e.g. txt.jiminny.com or txt.staging.jiminny.com# the Pub/Sub topic namaeu or us3. Run the svnc manualiv vin tinker tinside docker 1aeo 1%b bashaegdocker exec -it docker_lamp_1 php artisan tinkeapp(\Jiminny\Services\Ma1l\TextRelayService::class)-sync():Caveat: The service reads from Gmail history and dispatches jobs to the queue. If you don't want it to actuallsend SMS, make sure QUEUE_CONNECTICN»sync is not set (or use a test queue), or just call isForCurrentEnvironntioh.Ssvc = new class extends \Jiminny\Services\Mail\TextRelayService & public function _construct(som Serviceassvc-soctServicelcontiatainny.googletextI then sinsoect a eessade canual1sasg= sonailService-susers_messages-sget(config(*iminty.google text user'), *THE_MESSAGE ID*)collect(5-s0-20etPayload()-soetWeaders())-soluck("value"thut wey von can Mrity whht nandare tra nehhiim oraeset do ntas macesod aloca tha mill evoe mineAck amthine (oLCAhantiv• CNX M Maud Tosme 27/221 1TS9...
|
NULL
|
777383615227955681
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormCoocRurTool:WindowFV faVsco.|s ~$2 JY-2091 PhpStormCoocRurTool:WindowFV faVsco.|s ~$2 JY-20915-fix-mProinet vKerodloh© SyncMailbox.phpTMockarihM.CLAUDE mdlorkokyoemcelestonPyyminny.on3.env.productioncomposer.jsoncomooser ockclass Field extends Modeldependency-checker..somdew.sonF ids.txtintection.son.deMAINCTAIm85MAINSeNAws.wowcsnemjiminny_storageMallicaneae maM Makefile# package-lock.jsonphpstan.neon.distEphpstan-baseline.neo< phpunit.xmlraw-sal-query.saM: README ma& sonar-prolect.propertiesEtestiov<> Untitied Diagram.xmlas vetur.confiaieM.WEBHOOK_FILTERING.IMPLEMENTAT>1h Extemal Librariesv Scratches and ConsolesYteeostConotV AEUconsole auADEAL RISKS (EUToNTEUAEU (EU]ylliminnusochinostconsole tliminnweioch mosh#DI [EMAIL] fiminny@localhost)# SF (iminny@localhost)zoho-dev (iminny@localhost)V A PRODA console PROD# console 1 PRODADI (PROD'> AQA> AOAI>A QAI PRODV ASTAGINGA console (STAGING)111A uranus (STAGING)>M ExtensionsMScratchas123public const int NAME_MAX_LENGTH = 128:public const int LABEL_MAX_LENGTH = 255;public const int DESCRIPTION MAX LENGTH = 191:public const string TYPE_MULTIPICKLISI = 'nulti-picklist';Not yet supportedoublic const string TYPE_PERCENToublic const string TYPE_PICKLISTTYPE_NUMBERpublic const string TYPE_CURRENCYTYPE BOOLEANpublic const string TYPE_TEXTTYPE TEXTAREAqub sic const string tpE ErATqub sic const strind tNpe Uelmhe conet etaineivps luSibetetsne tuneunnonte.tpublic const string OBJECT_CALL• 'call':public const array STAGE_TYPE_FIELDS = [tontaunst on penvnse Sasesten ss iwtsoslseadThe Hunspell plugin has been deprecated. if you're not writing in Hungarian, you can safely uninstall Hunspell without affecting the dictionaries for other languages. (yesterday 15:44)laravel.logA console (STAGING)AA XA AYD000€POM activitales &IIN users u 1.nc->1: ON a.user_id = u.icJEREconedia eere& console (EU)Do jminny=24425826226326411II021 A1 A18 V2 Y6 Aa.status ='completedAno uurd to binc 64f1ac0-1608-4201-87126-075y079da08e=u.uusdAND a.deleted_at IS NULLANDSXTESAND + tune TM fiaudio! tusden!yIDER BY a.actual_start_time DESCJlort & foon toane whono id= 19.flect * fron crn configurations where provider = 'pipedrive"SISCTCONCAT(u.id, CASE WHEN u.id = t.ouner id THEN " (ouner)' ELSE ** END) AS user idv.enail,sa.*thouner1d FROM socilal accounts saJTN users u on uid = sa,sociable ioJTN teans t 1.nc-›1: on t5id = u.team idlJERE u,tean 1d = 19 and sa,oroviden = "pipedoive':SLECT * FROM social accounts WHERE 1d = 1116%DATE sochal accounte SET onowiden usen token = *VAu:AOTBAHS-L2TNK2yuuuaLo1f2hWb9ccUNKTok4F109cinXoo 6AE0h0h00Va1nvaCHEynovS)owiden nefresh token = [TELEGRAM_TOKEN]6944446h6b2bfc*)oines = 99891994JERE $d = 1116.provider_user-token": "viu:AQLBAH5-L2/NK2yuuuaLqifzh#b9crUNKtpk4F109minXap_6AE0hDhD0Va1nviiCHEvnpvSEAAAAf:1888gkqhk169w8BBwue779891992Mont &tmn en old vahuoc)ilect * fron crm fields where type = 'nulti-picklist':LECT * FROM Crn_ Layouts WHERE uuid_to_bin(*7C327871-4c25-4c56-9a0f-44c5a849d65c') = uuid;Sieo& Conken lewait onttoe nusoeonnloudtth202"BLEOT & EOOM onn Eioldo wuGOS 3a - 70141 # 1906SISOT & SOOM AN BOTH MOTHOG NHEOS An 31O12 12 C 791/2.TO0%L7Thu 28 May 9:31:05TextRelayServiceTestaer henseict+0.can I test it locally first. if I place env from stagingYes. The service relies on a tew thinas vou'd need in place1. Credentials file The constructor expects storage/text-relay.json (a Google service account JSON key file)Gmbtrom sthaind and oince it there2. .env values to copy from stagingGOOGLE TEXTUSERECOOGLE TEXTI HASTGOOGLE TEXT RELAY TOPIC:DEPLOY REGION:the cnail mailbox address# e.g. txt.jiminny.com or txt.staging.jiminny.com# the Pub/Sub topic namaeu or us3. Run the svnc manualiv vin tinker tinside docker 1aeo 1%b bashaegdocker exec -it docker_lamp_1 php artisan tinkeapp(\Jiminny\Services\Ma1l\TextRelayService::class)-sync():Caveat: The service reads from Gmail history and dispatches jobs to the queue. If you don't want it to actuallsend SMS, make sure QUEUE_CONNECTICN»sync is not set (or use a test queue), or just call isForCurrentEnvironntioh.Ssvc = new class extends \Jiminny\Services\Mail\TextRelayService & public function _construct(som Serviceassvc-soctServicelcontiatainny.googletextI then sinsoect a eessade canual1sasg= sonailService-susers_messages-sget(config(*iminty.google text user'), *THE_MESSAGE ID*)collect(5-s0-20etPayload()-soetWeaders())-soluck("value"thut wey von can Mrity whht nandare tra nehhiim oraeset do ntas macesod aloca tha mill evoe mineAck amthine (oLCAhantiv• CNX M Maud Tosme 27/221 1TS9...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79473
|
2787
|
43
|
2026-05-28T06:31:02.867334+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949862867_m2.jpg...
|
PhpStorm
|
faVsco.js – SF [jiminny@localhost]
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09740692,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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.8374335,"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}]...
|
-7635200922161528077
|
-4598385934329243181
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
=rnpstomFV faVsco.|s ~$2 JY-20915-fix-mlproidetM.CLAUDE mdcomposer.jsoncomooser ockdeoendency-checkercordew.sonids.txtintection.son.deMAINCTAImMAINSeNAws.wowcsnem=iiminny_storageMallicaneae maM Makefile# package-lock.jsonphpstan.neon.distEphpstan-baseline.neon<$ phpunit.xmlraw-sal-query.saM: README.md& sonar-prolect.propertiesEtestiov<> Untitied Diagram.xmlas vetur.confiaieM.WEBHOOK_FILTERING.IMPLEMENTAT>1h Extemal Librariesv Scratches and ConsolesYteeostConotconsole auADEAL RISKS (EUTAONTEUAEU (EU]ylliminnusochinostconsole lliminnyelocs nosh#DI [EMAIL] fiminny@localhost)# SF (iminny@localhost)zoho-dev (iminny@localhost)V A PRODA console PRODnancalo logeniA DI (PROD)> EDOA> MOAI> O QAI PROD• O STAGINGA console (STAGING)A console 1 (STAGING"A uranus (STAGING)>M ExtensionsMScratchasTho Huncnoll Nhhhin hac hoon Honro gtah Nua ttro maiCoocRurToolsWindow© SyncMailbox.phplorkokyoemcelestonfyyminny.oho3.env.productionclass Field extends Model85109116112public const int NAME_MAX_LENGTH = 128;public const int LABEL_MAX_LENGTH = 255;public const int DESCRIPTION MAX_ LENGTH = 191:public const string TYPE_MULTAPICKLIST = 'nulti-picklist':Not yet supportedoublic const string TYPE_PERCENToublic const string TYPE_PICKLISTTYPE_NUMBERpublic const string TYPE_CURRENCYTYPE BOOLEANpublic const string TYPE_TEXTpublic const string TYPE_EHATLpublic const string TYPE_URLpublic const string TYPE_DATETINEpublic const string TYPE_UNSUPPORTED = "unsupported"muhile conet etand nRistspublic const string OBJECT_ACCOUN,nuhlie conet ctaion NRIGAY CAMTAMpublic const string OBJECT_OPPORTUNITY = 'opportunity"public const string OBJECT_TASKewtachtpublic const string OBJECT-EVENToublic const string OBJECT CALI• 'call':public const string OBJECT_MEETING'neeting':public const arpay BUSTNESS_TYPE_FTELDS #Configuratsion::PROVTDER SALESFORCE = "Tvpe"vonroursdontrexuwliekehuu=> "dealtyoe'.1:oublic const arnay PYPELINE TYPE FTELOS =Confstqunatsion::PROVIDER HUBSPOTpublic const array STAGE_TYPE_FIELDS = [tontaunst on penvnse Sasesten ss iwtsoslseadg in Hungarian, you can safely uninstall Hunspeli without affecting the dictionaries for other languages. (yesterday 15:44)S0TOOУLYTextRelayServiceTestIno Lo moy DioiuWMockarhitlaravel.logA console (STAGING)E| AALAAY D6000POM activitales &IIN users u 1.nc->1: ON a.user_id = u.icEREconedla erre& console (EU)Do jminny=24425826226326411IIa8lbiYyoea.status = 'completedAno uurd co bind 6411800-1608-4201-8726-4757079da08eD = u.uusdAND a.deleted_at IS NULLANDSXTESAND + tune TM Giaudio! tusdeo!yIDER BY a.actual_start_time DESCJlort & foon toane whono id= 19.flect * fron crn configurations where provider = 'pipedrive"SISCTCONCAT(u.id, CASE WHEN u.id = t.ouner id THEN " (ouner)' ELSE ** END) AS user idv.enail,sa.*thouner1d FROM socilal accounts saJTN users u on uid = sa,sociable ioJTN teans t 1.nc-›1: on t5id = u.team idlJERE u,tean s1d = 19 and sa,prowider = "pioedoive":SLECT * FROM social accounts WHERE 1d = 1116%DATE sochal accounte SET onowiden usen token = *VAu:AOTBAHS-L2TNK2yuuuaLo1f2hWb9ccUNKTok4F109cinXoo 6AE0h0h00Va1nvalCHEynovS)owiden nefresh token = [TELEGRAM_TOKEN]6944446h6b2bfc*)oines = 99891994JERE $d = 1116.provider_user-token": "viu:AQLBAH5-L2/NK2yuuuaLqifzh#b9crUNKtpk4F109minXap_6AE0hDhD0Va1nviiCHEvnpvSEAAAAf:1888gkqhk169w8BBwuel779891992Mont &tmn en old vahuoc)ilect * fron crm fields where type = 'nulti-picklist':LECT * FROM Crn_ Layouts WHERE uuid_to_bin(*7C327871-4c25-4c56-9a0f-44c5a849d65c') = uuid;Sieo& conkeng ieuait onttoe Nusoeonnloudtth202"BLEOT & EOOM onn Eioldo wuGOS 3a - 70141 # 1906SISOT & SOOM AN BOTH MOTHOG NHEOS An 31O12 12 C 791/2.eeendh...
|
79471
|
NULL
|
NULL
|
NULL
|
|
79472
|
2786
|
21
|
2026-05-28T06:31:02.007824+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949862007_m1.jpg...
|
PhpStorm
|
faVsco.js – SF [jiminny@localhost]
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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":"TextRelayServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'TextRelayServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'TextRelayServiceTest'","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}]...
|
-7228688528716742632
|
2609222811515291121
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
iTerm2ShellEditViewSessionScriptsProfilesWindowHelp‹$0DOCKER-₴81DEV (docker)₴2-zsh-zshscreenpipe"84-zsh*5100% <478•Thu 28 May 9:31:01181...ip-10-30-129-190:~ (nc)₴86...-10-30-140-255:~ (-zsh)$7Fixed 0 of 5697 files in 55.554 seconds, 799.06 MBmemory usedDetected deprecations in use (they will stop working in next major release):Rule set"@PHP74Migration"is deprecated.Use"@PHP7x4Migration"instead.- Rule set "@PHP80Migration"is deprecated.Use "@PHP8x0Migration"instead.Rule set "@PHP81Migration" is deprecated. Use "@PHP8x1Migration"instead.Rule set "@PHP82Migration" is deprecated. Use "@PHP8x2Migration" instead.Rule set "@PHP83Migration" is deprecated.Use"@PHP8x3Migration" instead.Rule set "@PHP84Migration" is deprecated.Use "@PHP8x4Migration" instead.What's next:Try Docker Debug for seamless, persistent debugging tools in any container or image docker debug docker_lamp_1Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20915-fix-strict-casting-text-relay-service) $ co masterM.env.localMapp/Console/Commands/JiminnyDebugCommand.phpconfig/logging.phpSwitched to branch'master'Your branch is up to date with 'origin/master'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullremote: Enumerating objects: 97,done.remote: Countingobjects: 100% (97/97),done.remote: Compressing objects: 100% (27/27), done.remote: Total 97 (delta 69), reused 95 (delta 69), pack-reused 0 (from 0)Unpacking objects: 100% (97/97), 14.08 KiB | 150.00 KiB/s, done.From github.com:jiminny/appf1ccf9be50..890e429206master-> origin/masterce9abde868..3800efb7ea JY-20905-tool-search-members-> origin/JY-20905-tool-search-membersad6ace97b9..b3659b1290JY-20910-schedule-parallel-update-target-processing -> origin/JY-20910-schedule-parallel-update-target-processingUpdating f1ccf9be50..890e429206Fast-forwardapp/Services/Mail/TextRelayService.php6tests/Unit/Services/Mail/TextRelayServiceTest.php1132 files changed, 14 insertions(+),5 deletions(-)lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20915-fix-missing-header-text-relaySwitched to a new branch 'JY-20915-fix-missing-header-text-relay'Lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $D...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79471
|
2787
|
42
|
2026-05-28T06:31:01.903174+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949861903_m2.jpg...
|
PhpStorm
|
faVsco.js – SF [jiminny@localhost]
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
42
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models\Crm;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Jiminny\Component\Eloquent\Builder;
use Jiminny\Models\Ai\CrmTemplateField;
use Jiminny\Models\Model;
use Jiminny\Models\Playbook;
use Jiminny\Services\Crm\CrmObjects\FieldReadonlyConstants;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
/**
* Jiminny\Models\Crm\Field
*
* @property int $id
* @property mixed|null $uuid
* @property int $crm_configuration_id
* @property string $crm_provider_id
* @property string $label
* @property string|null $description
* @property string $type
* @property int|null $length
* @property string|null $default_value
* @property string $object_type
* @property bool $is_selectable
* @property bool $is_mandatory
* @property bool $is_filterable
* @property bool $is_indexable
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Jiminny\Models\Crm\Configuration $configuration
* @property-read \Jiminny\Models\Crm\Configuration $crm
* @property-read Collection<int, \Jiminny\Models\Crm\FieldData> $data
* @property-read int|null $data_count
* @property-read Collection<int, \Jiminny\Models\Crm\LayoutEntity> $entities
* @property-read int|null $entities_count
* @property-read string $id_string
* @property-read Collection<int, \Jiminny\Models\Crm\FieldValue> $values
* @property-read int|null $values_count
*
* @method static Builder|Field chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\Crm\FieldFactory factory(...$parameters)
* @method static Builder|Field idOrUuId($idOrUuid, bool $first = true)
* @method static Builder|Field indexable()
* @method static Builder|Field newModelQuery()
* @method static Builder|Field newQuery()
* @method static Builder|Field query()
* @method static Builder|Field tasks()
* @method static Builder|Field uuid(string $uuid, bool $first = true)
* @method static Builder|Field whereCreatedAt($value)
* @method static Builder|Field whereCrmConfigurationId($value)
* @method static Builder|Field whereCrmProviderId($value)
* @method static Builder|Field whereDefaultValue($value)
* @method static Builder|Field whereDescription($value)
* @method static Builder|Field whereId($value)
* @method static Builder|Field whereIsFilterable($value)
* @method static Builder|Field whereIsIndexable($value)
* @method static Builder|Field whereIsMandatory($value)
* @method static Builder|Field whereIsSelectable($value)
* @method static Builder|Field whereLabel($value)
* @method static Builder|Field whereLength($value)
* @method static Builder|Field whereObjectType($value)
* @method static Builder|Field whereType($value)
* @method static Builder|Field whereUpdatedAt($value)
* @method static Builder|Field whereUuid($value)
*
* @mixin \Eloquent
*/
class Field extends Model
{
use HasFactory;
use RequiresUUID;
use Enums;
public const int NAME_MAX_LENGTH = 128;
public const int LABEL_MAX_LENGTH = 255;
public const int DESCRIPTION_MAX_LENGTH = 191;
public const string TYPE_MULTIPICKLIST = 'multi-picklist';
// Not yet supported
public const string TYPE_PERCENT = 'percent';
public const string TYPE_PICKLIST = 'picklist';
public const string TYPE_NUMBER = 'number';
public const string TYPE_CURRENCY = 'currency';
public const string TYPE_BOOLEAN = 'boolean';
public const string TYPE_TEXT = 'text';
public const string TYPE_TEXTAREA = 'textarea';
public const string TYPE_EMAIL = 'email';
public const string TYPE_PHONE = 'phone';
public const string TYPE_URL = 'url';
public const string TYPE_DATE = 'date';
public const string TYPE_TIME = 'time';
public const string TYPE_DATETIME = 'datetime';
public const string TYPE_UNSUPPORTED = 'unsupported';
public const string OBJECT_LEAD = 'lead';
public const string OBJECT_ACCOUNT = 'account';
public const string OBJECT_CONTACT = 'contact';
public const string OBJECT_OPPORTUNITY = 'opportunity';
public const string OBJECT_TASK = 'task';
public const string OBJECT_EVENT = 'event';
public const string OBJECT_CALL = 'call';
public const string OBJECT_MEETING = 'meeting';
public const array BUSINESS_TYPE_FIELDS = [
Configuration::PROVIDER_SALESFORCE => 'Type',
Configuration::PROVIDER_HUBSPOT => 'dealtype',
];
public const array PIPELINE_TYPE_FIELDS = [
Configuration::PROVIDER_HUBSPOT => 'pipeline',
];
public const array STAGE_TYPE_FIELDS = [
Configuration::PROVIDER_SALESFORCE => 'StageName',
Configuration::PROVIDER_HUBSPOT => 'dealstage',
Configuration::PROVIDER_CLOSE => 'status_id',
Configuration::PROVIDER_BULLHORN => 'status',
Configuration::PROVIDER_PIPEDRIVE => 'stage_id',
Configuration::PROVIDER_COPPER => 'pipeline_stage_id',
];
public static $enumTypes = [
self::TYPE_PICKLIST,
self::TYPE_NUMBER,
self::TYPE_CURRENCY,
self::TYPE_BOOLEAN,
self::TYPE_TEXT,
self::TYPE_TEXTAREA,
self::TYPE_EMAIL,
self::TYPE_PHONE,
self::TYPE_URL,
self::TYPE_DATE,
self::TYPE_TIME,
self::TYPE_DATETIME,
self::TYPE_UNSUPPORTED,
];
public static $enumObjectTypes = [
self::OBJECT_LEAD,
self::OBJECT_ACCOUNT,
self::OBJECT_CONTACT,
self::OBJECT_OPPORTUNITY,
self::OBJECT_TASK,
self::OBJECT_EVENT,
];
protected $table = 'crm_fields';
protected $fillable = [
'crm_configuration_id',
'crm_provider_id',
'object_type',
'type',
'label',
'description',
'is_selectable',
'is_mandatory',
'length',
'default_value',
'is_indexable',
'is_filterable',
'is_readonly',
];
protected $appends = [
'id_string',
];
protected $hidden = [
'uuid',
'id',
'crm_configuration_id',
];
protected function casts(): array
{
return [
'is_selectable' => 'boolean',
'is_mandatory' => 'boolean',
'is_indexable' => 'boolean',
'is_filterable' => 'boolean',
];
}
public function configuration(): BelongsTo
{
return $this->belongsTo(Configuration::class, 'crm_configuration_id');
}
public function entities(): HasMany
{
return $this->hasMany(LayoutEntity::class, 'crm_field_id');
}
public function getEntities(): Collection
{
/** @var Collection<LayoutEntity> $entities */
$entities = $this->getAttribute('entities');
return $entities;
}
public function values(): HasMany
{
return $this->hasMany(FieldValue::class, 'crm_field_id')->orderBy('sequence');
}
public function getLabel(): string
{
return $this->getAttribute('label');
}
public function getType(): string
{
return $this->getAttribute('type');
}
public function getObjectType(): string
{
/** @var string */
return $this->getAttribute('object_type');
}
public function getCrmProviderId(): string
{
/** @var string */
return $this->getAttribute('crm_provider_id');
}
public function getValues(): Collection
{
return $this->getAttribute('values');
}
public function isIndexable(): bool
{
return $this->getAttribute('is_indexable');
}
public function isFilterable(): bool
{
return $this->getAttribute('is_filterable');
}
public function getId(): int
{
/** @var int */
return $this->getAttribute('id');
}
public function hasDescription(): bool
{
return $this->getAttribute('description') !== null;
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function data()
{
return $this->hasMany(FieldData::class, 'crm_field_id');
}
public function crm(): BelongsTo
{
return $this->belongsTo(Configuration::class, 'crm_configuration_id');
}
#[Scope]
protected function indexable($query)
{
return $query->where('is_indexable', 1);
}
#[Scope]
protected function tasks($query)
{
return $query->where('object_type', self::OBJECT_TASK);
}
public function isBusinessType(): bool
{
return in_array($this->getCrmProviderId(), self::BUSINESS_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function isStageField(): bool
{
return in_array($this->getCrmProviderId(), self::STAGE_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function isPipelineField(): bool
{
return in_array($this->getCrmProviderId(), self::PIPELINE_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function getUuid(): string
{
return $this->getAttribute('id_string');
}
public function getCrmConfiguration(): Configuration
{
return $this->getAttribute('crm');
}
public function getCrmConfigurationId(): int
{
return $this->getAttribute('crm_configuration_id');
}
/**
* Currently implemented only for Opportunity fields
*/
public function isReadOnly(): bool
{
// The CRM Field metadata should always be first to be taken into consideration.
if ($this->getIsReadonly()) {
return true;
}
if ($this->getObjectType() !== self::OBJECT_OPPORTUNITY) {
return false;
}
if ($this->isPipelineField()) {
return true;
}
if ($this->getType() === Field::TYPE_UNSUPPORTED) {
return true;
}
if ($this->getCrmConfiguration()->getProviderName() === Configuration::PROVIDER_INTEGRATION_APP) {
$fieldDefinitions = new CrmFieldDefinitionsManager();
return $fieldDefinitions->isReadOnly($this->getCrmProviderId(), self::OBJECT_OPPORTUNITY);
}
return false;
}
public function isPicklist(): bool
{
return in_array($this->getType(), [self::TYPE_PICKLIST, self::TYPE_MULTIPICKLIST]);
}
public function getLength(): ?int
{
return $this->getAttribute('length');
}
public function getDefaultValue(): ?string
{
return $this->getAttribute('default_value');
}
public function setIsReadonly(int $isReadonly): void
{
$this->setAttribute('is_readonly', $isReadonly);
}
public function getIsReadonly(): bool
{
return $this->getAttribute('is_readonly') !== FieldReadonlyConstants::FIELD_IS_UPDATABLE;
}
public function getEntityName(): string
{
return ucfirst($this->getObjectType()) . '.' . $this->getCrmProviderId();
}
public function crmTemplateFields(): HasMany
{
return $this->hasMany(CrmTemplateField::class, 'crm_field_id');
}
public function playbooks(): HasMany
{
return $this->hasMany(Playbook::class, 'activity_field_id');
}
public function getPlaybooks(): Collection
{
return $this->getAttribute('playbooks');
}
}
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
21
1
18...
|
[{"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-20915-fix-missing-header-text-relay, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09740692,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20915-fix-missing-header-text-relay","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.8374335,"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":"TextRelayServiceTest","depth":6,"bounds":{"left":0.85272604,"top":0.019952115,"width":0.062832445,"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 'TextRelayServiceTest'","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 'TextRelayServiceTest'","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":"42","depth":4,"bounds":{"left":0.375,"top":0.10055866,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.38730052,"top":0.10055866,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39694148,"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.40425533,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Models\\Crm;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Jiminny\\Component\\Eloquent\\Builder;\nuse Jiminny\\Models\\Ai\\CrmTemplateField;\nuse Jiminny\\Models\\Model;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Services\\Crm\\CrmObjects\\FieldReadonlyConstants;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\n\n/**\n * Jiminny\\Models\\Crm\\Field\n *\n * @property int $id\n * @property mixed|null $uuid\n * @property int $crm_configuration_id\n * @property string $crm_provider_id\n * @property string $label\n * @property string|null $description\n * @property string $type\n * @property int|null $length\n * @property string|null $default_value\n * @property string $object_type\n * @property bool $is_selectable\n * @property bool $is_mandatory\n * @property bool $is_filterable\n * @property bool $is_indexable\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property-read \\Jiminny\\Models\\Crm\\Configuration $configuration\n * @property-read \\Jiminny\\Models\\Crm\\Configuration $crm\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\FieldData> $data\n * @property-read int|null $data_count\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\LayoutEntity> $entities\n * @property-read int|null $entities_count\n * @property-read string $id_string\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\FieldValue> $values\n * @property-read int|null $values_count\n *\n * @method static Builder|Field chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\Crm\\FieldFactory factory(...$parameters)\n * @method static Builder|Field idOrUuId($idOrUuid, bool $first = true)\n * @method static Builder|Field indexable()\n * @method static Builder|Field newModelQuery()\n * @method static Builder|Field newQuery()\n * @method static Builder|Field query()\n * @method static Builder|Field tasks()\n * @method static Builder|Field uuid(string $uuid, bool $first = true)\n * @method static Builder|Field whereCreatedAt($value)\n * @method static Builder|Field whereCrmConfigurationId($value)\n * @method static Builder|Field whereCrmProviderId($value)\n * @method static Builder|Field whereDefaultValue($value)\n * @method static Builder|Field whereDescription($value)\n * @method static Builder|Field whereId($value)\n * @method static Builder|Field whereIsFilterable($value)\n * @method static Builder|Field whereIsIndexable($value)\n * @method static Builder|Field whereIsMandatory($value)\n * @method static Builder|Field whereIsSelectable($value)\n * @method static Builder|Field whereLabel($value)\n * @method static Builder|Field whereLength($value)\n * @method static Builder|Field whereObjectType($value)\n * @method static Builder|Field whereType($value)\n * @method static Builder|Field whereUpdatedAt($value)\n * @method static Builder|Field whereUuid($value)\n *\n * @mixin \\Eloquent\n */\nclass Field extends Model\n{\n use HasFactory;\n\n use RequiresUUID;\n use Enums;\n\n public const int NAME_MAX_LENGTH = 128;\n public const int LABEL_MAX_LENGTH = 255;\n public const int DESCRIPTION_MAX_LENGTH = 191;\n\n public const string TYPE_MULTIPICKLIST = 'multi-picklist';\n // Not yet supported\n public const string TYPE_PERCENT = 'percent';\n\n public const string TYPE_PICKLIST = 'picklist';\n public const string TYPE_NUMBER = 'number';\n public const string TYPE_CURRENCY = 'currency';\n public const string TYPE_BOOLEAN = 'boolean';\n public const string TYPE_TEXT = 'text';\n public const string TYPE_TEXTAREA = 'textarea';\n public const string TYPE_EMAIL = 'email';\n public const string TYPE_PHONE = 'phone';\n public const string TYPE_URL = 'url';\n public const string TYPE_DATE = 'date';\n public const string TYPE_TIME = 'time';\n public const string TYPE_DATETIME = 'datetime';\n public const string TYPE_UNSUPPORTED = 'unsupported';\n\n public const string OBJECT_LEAD = 'lead';\n public const string OBJECT_ACCOUNT = 'account';\n public const string OBJECT_CONTACT = 'contact';\n public const string OBJECT_OPPORTUNITY = 'opportunity';\n public const string OBJECT_TASK = 'task';\n public const string OBJECT_EVENT = 'event';\n public const string OBJECT_CALL = 'call';\n public const string OBJECT_MEETING = 'meeting';\n\n public const array BUSINESS_TYPE_FIELDS = [\n Configuration::PROVIDER_SALESFORCE => 'Type',\n Configuration::PROVIDER_HUBSPOT => 'dealtype',\n ];\n\n public const array PIPELINE_TYPE_FIELDS = [\n Configuration::PROVIDER_HUBSPOT => 'pipeline',\n ];\n\n public const array STAGE_TYPE_FIELDS = [\n Configuration::PROVIDER_SALESFORCE => 'StageName',\n Configuration::PROVIDER_HUBSPOT => 'dealstage',\n Configuration::PROVIDER_CLOSE => 'status_id',\n Configuration::PROVIDER_BULLHORN => 'status',\n Configuration::PROVIDER_PIPEDRIVE => 'stage_id',\n Configuration::PROVIDER_COPPER => 'pipeline_stage_id',\n ];\n\n public static $enumTypes = [\n self::TYPE_PICKLIST,\n self::TYPE_NUMBER,\n self::TYPE_CURRENCY,\n self::TYPE_BOOLEAN,\n self::TYPE_TEXT,\n self::TYPE_TEXTAREA,\n self::TYPE_EMAIL,\n self::TYPE_PHONE,\n self::TYPE_URL,\n self::TYPE_DATE,\n self::TYPE_TIME,\n self::TYPE_DATETIME,\n self::TYPE_UNSUPPORTED,\n ];\n\n public static $enumObjectTypes = [\n self::OBJECT_LEAD,\n self::OBJECT_ACCOUNT,\n self::OBJECT_CONTACT,\n self::OBJECT_OPPORTUNITY,\n self::OBJECT_TASK,\n self::OBJECT_EVENT,\n ];\n\n protected $table = 'crm_fields';\n\n protected $fillable = [\n 'crm_configuration_id',\n 'crm_provider_id',\n 'object_type',\n 'type',\n 'label',\n 'description',\n 'is_selectable',\n 'is_mandatory',\n 'length',\n 'default_value',\n 'is_indexable',\n 'is_filterable',\n 'is_readonly',\n ];\n\n protected $appends = [\n 'id_string',\n ];\n\n protected $hidden = [\n 'uuid',\n 'id',\n 'crm_configuration_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'is_selectable' => 'boolean',\n 'is_mandatory' => 'boolean',\n 'is_indexable' => 'boolean',\n 'is_filterable' => 'boolean',\n ];\n }\n\n public function configuration(): BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function entities(): HasMany\n {\n return $this->hasMany(LayoutEntity::class, 'crm_field_id');\n }\n\n public function getEntities(): Collection\n {\n /** @var Collection<LayoutEntity> $entities */\n $entities = $this->getAttribute('entities');\n\n return $entities;\n }\n\n public function values(): HasMany\n {\n return $this->hasMany(FieldValue::class, 'crm_field_id')->orderBy('sequence');\n }\n\n public function getLabel(): string\n {\n return $this->getAttribute('label');\n }\n\n public function getType(): string\n {\n return $this->getAttribute('type');\n }\n\n public function getObjectType(): string\n {\n /** @var string */\n return $this->getAttribute('object_type');\n }\n\n public function getCrmProviderId(): string\n {\n /** @var string */\n return $this->getAttribute('crm_provider_id');\n }\n\n public function getValues(): Collection\n {\n return $this->getAttribute('values');\n }\n\n public function isIndexable(): bool\n {\n return $this->getAttribute('is_indexable');\n }\n\n public function isFilterable(): bool\n {\n return $this->getAttribute('is_filterable');\n }\n\n public function getId(): int\n {\n /** @var int */\n return $this->getAttribute('id');\n }\n\n public function hasDescription(): bool\n {\n return $this->getAttribute('description') !== null;\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function data()\n {\n return $this->hasMany(FieldData::class, 'crm_field_id');\n }\n\n public function crm(): BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n #[Scope]\n protected function indexable($query)\n {\n return $query->where('is_indexable', 1);\n }\n\n #[Scope]\n protected function tasks($query)\n {\n return $query->where('object_type', self::OBJECT_TASK);\n }\n\n public function isBusinessType(): bool\n {\n return in_array($this->getCrmProviderId(), self::BUSINESS_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function isStageField(): bool\n {\n return in_array($this->getCrmProviderId(), self::STAGE_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function isPipelineField(): bool\n {\n return in_array($this->getCrmProviderId(), self::PIPELINE_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getCrmConfiguration(): Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function getCrmConfigurationId(): int\n {\n return $this->getAttribute('crm_configuration_id');\n }\n\n /**\n * Currently implemented only for Opportunity fields\n */\n public function isReadOnly(): bool\n {\n // The CRM Field metadata should always be first to be taken into consideration.\n if ($this->getIsReadonly()) {\n return true;\n }\n\n if ($this->getObjectType() !== self::OBJECT_OPPORTUNITY) {\n return false;\n }\n\n if ($this->isPipelineField()) {\n return true;\n }\n\n if ($this->getType() === Field::TYPE_UNSUPPORTED) {\n return true;\n }\n\n if ($this->getCrmConfiguration()->getProviderName() === Configuration::PROVIDER_INTEGRATION_APP) {\n $fieldDefinitions = new CrmFieldDefinitionsManager();\n\n return $fieldDefinitions->isReadOnly($this->getCrmProviderId(), self::OBJECT_OPPORTUNITY);\n }\n\n return false;\n }\n\n public function isPicklist(): bool\n {\n return in_array($this->getType(), [self::TYPE_PICKLIST, self::TYPE_MULTIPICKLIST]);\n }\n\n public function getLength(): ?int\n {\n return $this->getAttribute('length');\n }\n\n public function getDefaultValue(): ?string\n {\n return $this->getAttribute('default_value');\n }\n\n public function setIsReadonly(int $isReadonly): void\n {\n $this->setAttribute('is_readonly', $isReadonly);\n }\n\n public function getIsReadonly(): bool\n {\n return $this->getAttribute('is_readonly') !== FieldReadonlyConstants::FIELD_IS_UPDATABLE;\n }\n\n public function getEntityName(): string\n {\n return ucfirst($this->getObjectType()) . '.' . $this->getCrmProviderId();\n }\n\n public function crmTemplateFields(): HasMany\n {\n return $this->hasMany(CrmTemplateField::class, 'crm_field_id');\n }\n\n public function playbooks(): HasMany\n {\n return $this->hasMany(Playbook::class, 'activity_field_id');\n }\n\n public function getPlaybooks(): Collection\n {\n return $this->getAttribute('playbooks');\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Models\\Crm;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Jiminny\\Component\\Eloquent\\Builder;\nuse Jiminny\\Models\\Ai\\CrmTemplateField;\nuse Jiminny\\Models\\Model;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Services\\Crm\\CrmObjects\\FieldReadonlyConstants;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\n\n/**\n * Jiminny\\Models\\Crm\\Field\n *\n * @property int $id\n * @property mixed|null $uuid\n * @property int $crm_configuration_id\n * @property string $crm_provider_id\n * @property string $label\n * @property string|null $description\n * @property string $type\n * @property int|null $length\n * @property string|null $default_value\n * @property string $object_type\n * @property bool $is_selectable\n * @property bool $is_mandatory\n * @property bool $is_filterable\n * @property bool $is_indexable\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property-read \\Jiminny\\Models\\Crm\\Configuration $configuration\n * @property-read \\Jiminny\\Models\\Crm\\Configuration $crm\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\FieldData> $data\n * @property-read int|null $data_count\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\LayoutEntity> $entities\n * @property-read int|null $entities_count\n * @property-read string $id_string\n * @property-read Collection<int, \\Jiminny\\Models\\Crm\\FieldValue> $values\n * @property-read int|null $values_count\n *\n * @method static Builder|Field chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\Crm\\FieldFactory factory(...$parameters)\n * @method static Builder|Field idOrUuId($idOrUuid, bool $first = true)\n * @method static Builder|Field indexable()\n * @method static Builder|Field newModelQuery()\n * @method static Builder|Field newQuery()\n * @method static Builder|Field query()\n * @method static Builder|Field tasks()\n * @method static Builder|Field uuid(string $uuid, bool $first = true)\n * @method static Builder|Field whereCreatedAt($value)\n * @method static Builder|Field whereCrmConfigurationId($value)\n * @method static Builder|Field whereCrmProviderId($value)\n * @method static Builder|Field whereDefaultValue($value)\n * @method static Builder|Field whereDescription($value)\n * @method static Builder|Field whereId($value)\n * @method static Builder|Field whereIsFilterable($value)\n * @method static Builder|Field whereIsIndexable($value)\n * @method static Builder|Field whereIsMandatory($value)\n * @method static Builder|Field whereIsSelectable($value)\n * @method static Builder|Field whereLabel($value)\n * @method static Builder|Field whereLength($value)\n * @method static Builder|Field whereObjectType($value)\n * @method static Builder|Field whereType($value)\n * @method static Builder|Field whereUpdatedAt($value)\n * @method static Builder|Field whereUuid($value)\n *\n * @mixin \\Eloquent\n */\nclass Field extends Model\n{\n use HasFactory;\n\n use RequiresUUID;\n use Enums;\n\n public const int NAME_MAX_LENGTH = 128;\n public const int LABEL_MAX_LENGTH = 255;\n public const int DESCRIPTION_MAX_LENGTH = 191;\n\n public const string TYPE_MULTIPICKLIST = 'multi-picklist';\n // Not yet supported\n public const string TYPE_PERCENT = 'percent';\n\n public const string TYPE_PICKLIST = 'picklist';\n public const string TYPE_NUMBER = 'number';\n public const string TYPE_CURRENCY = 'currency';\n public const string TYPE_BOOLEAN = 'boolean';\n public const string TYPE_TEXT = 'text';\n public const string TYPE_TEXTAREA = 'textarea';\n public const string TYPE_EMAIL = 'email';\n public const string TYPE_PHONE = 'phone';\n public const string TYPE_URL = 'url';\n public const string TYPE_DATE = 'date';\n public const string TYPE_TIME = 'time';\n public const string TYPE_DATETIME = 'datetime';\n public const string TYPE_UNSUPPORTED = 'unsupported';\n\n public const string OBJECT_LEAD = 'lead';\n public const string OBJECT_ACCOUNT = 'account';\n public const string OBJECT_CONTACT = 'contact';\n public const string OBJECT_OPPORTUNITY = 'opportunity';\n public const string OBJECT_TASK = 'task';\n public const string OBJECT_EVENT = 'event';\n public const string OBJECT_CALL = 'call';\n public const string OBJECT_MEETING = 'meeting';\n\n public const array BUSINESS_TYPE_FIELDS = [\n Configuration::PROVIDER_SALESFORCE => 'Type',\n Configuration::PROVIDER_HUBSPOT => 'dealtype',\n ];\n\n public const array PIPELINE_TYPE_FIELDS = [\n Configuration::PROVIDER_HUBSPOT => 'pipeline',\n ];\n\n public const array STAGE_TYPE_FIELDS = [\n Configuration::PROVIDER_SALESFORCE => 'StageName',\n Configuration::PROVIDER_HUBSPOT => 'dealstage',\n Configuration::PROVIDER_CLOSE => 'status_id',\n Configuration::PROVIDER_BULLHORN => 'status',\n Configuration::PROVIDER_PIPEDRIVE => 'stage_id',\n Configuration::PROVIDER_COPPER => 'pipeline_stage_id',\n ];\n\n public static $enumTypes = [\n self::TYPE_PICKLIST,\n self::TYPE_NUMBER,\n self::TYPE_CURRENCY,\n self::TYPE_BOOLEAN,\n self::TYPE_TEXT,\n self::TYPE_TEXTAREA,\n self::TYPE_EMAIL,\n self::TYPE_PHONE,\n self::TYPE_URL,\n self::TYPE_DATE,\n self::TYPE_TIME,\n self::TYPE_DATETIME,\n self::TYPE_UNSUPPORTED,\n ];\n\n public static $enumObjectTypes = [\n self::OBJECT_LEAD,\n self::OBJECT_ACCOUNT,\n self::OBJECT_CONTACT,\n self::OBJECT_OPPORTUNITY,\n self::OBJECT_TASK,\n self::OBJECT_EVENT,\n ];\n\n protected $table = 'crm_fields';\n\n protected $fillable = [\n 'crm_configuration_id',\n 'crm_provider_id',\n 'object_type',\n 'type',\n 'label',\n 'description',\n 'is_selectable',\n 'is_mandatory',\n 'length',\n 'default_value',\n 'is_indexable',\n 'is_filterable',\n 'is_readonly',\n ];\n\n protected $appends = [\n 'id_string',\n ];\n\n protected $hidden = [\n 'uuid',\n 'id',\n 'crm_configuration_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'is_selectable' => 'boolean',\n 'is_mandatory' => 'boolean',\n 'is_indexable' => 'boolean',\n 'is_filterable' => 'boolean',\n ];\n }\n\n public function configuration(): BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function entities(): HasMany\n {\n return $this->hasMany(LayoutEntity::class, 'crm_field_id');\n }\n\n public function getEntities(): Collection\n {\n /** @var Collection<LayoutEntity> $entities */\n $entities = $this->getAttribute('entities');\n\n return $entities;\n }\n\n public function values(): HasMany\n {\n return $this->hasMany(FieldValue::class, 'crm_field_id')->orderBy('sequence');\n }\n\n public function getLabel(): string\n {\n return $this->getAttribute('label');\n }\n\n public function getType(): string\n {\n return $this->getAttribute('type');\n }\n\n public function getObjectType(): string\n {\n /** @var string */\n return $this->getAttribute('object_type');\n }\n\n public function getCrmProviderId(): string\n {\n /** @var string */\n return $this->getAttribute('crm_provider_id');\n }\n\n public function getValues(): Collection\n {\n return $this->getAttribute('values');\n }\n\n public function isIndexable(): bool\n {\n return $this->getAttribute('is_indexable');\n }\n\n public function isFilterable(): bool\n {\n return $this->getAttribute('is_filterable');\n }\n\n public function getId(): int\n {\n /** @var int */\n return $this->getAttribute('id');\n }\n\n public function hasDescription(): bool\n {\n return $this->getAttribute('description') !== null;\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function data()\n {\n return $this->hasMany(FieldData::class, 'crm_field_id');\n }\n\n public function crm(): BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n #[Scope]\n protected function indexable($query)\n {\n return $query->where('is_indexable', 1);\n }\n\n #[Scope]\n protected function tasks($query)\n {\n return $query->where('object_type', self::OBJECT_TASK);\n }\n\n public function isBusinessType(): bool\n {\n return in_array($this->getCrmProviderId(), self::BUSINESS_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function isStageField(): bool\n {\n return in_array($this->getCrmProviderId(), self::STAGE_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function isPipelineField(): bool\n {\n return in_array($this->getCrmProviderId(), self::PIPELINE_TYPE_FIELDS)\n && $this->getObjectType() === self::OBJECT_OPPORTUNITY;\n }\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getCrmConfiguration(): Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function getCrmConfigurationId(): int\n {\n return $this->getAttribute('crm_configuration_id');\n }\n\n /**\n * Currently implemented only for Opportunity fields\n */\n public function isReadOnly(): bool\n {\n // The CRM Field metadata should always be first to be taken into consideration.\n if ($this->getIsReadonly()) {\n return true;\n }\n\n if ($this->getObjectType() !== self::OBJECT_OPPORTUNITY) {\n return false;\n }\n\n if ($this->isPipelineField()) {\n return true;\n }\n\n if ($this->getType() === Field::TYPE_UNSUPPORTED) {\n return true;\n }\n\n if ($this->getCrmConfiguration()->getProviderName() === Configuration::PROVIDER_INTEGRATION_APP) {\n $fieldDefinitions = new CrmFieldDefinitionsManager();\n\n return $fieldDefinitions->isReadOnly($this->getCrmProviderId(), self::OBJECT_OPPORTUNITY);\n }\n\n return false;\n }\n\n public function isPicklist(): bool\n {\n return in_array($this->getType(), [self::TYPE_PICKLIST, self::TYPE_MULTIPICKLIST]);\n }\n\n public function getLength(): ?int\n {\n return $this->getAttribute('length');\n }\n\n public function getDefaultValue(): ?string\n {\n return $this->getAttribute('default_value');\n }\n\n public function setIsReadonly(int $isReadonly): void\n {\n $this->setAttribute('is_readonly', $isReadonly);\n }\n\n public function getIsReadonly(): bool\n {\n return $this->getAttribute('is_readonly') !== FieldReadonlyConstants::FIELD_IS_UPDATABLE;\n }\n\n public function getEntityName(): string\n {\n return ucfirst($this->getObjectType()) . '.' . $this->getCrmProviderId();\n }\n\n public function crmTemplateFields(): HasMany\n {\n return $this->hasMany(CrmTemplateField::class, 'crm_field_id');\n }\n\n public function playbooks(): HasMany\n {\n return $this->hasMany(Playbook::class, 'activity_field_id');\n }\n\n public function getPlaybooks(): Collection\n {\n return $this->getAttribute('playbooks');\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.41289893,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"bounds":{"left":0.42154256,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"bounds":{"left":0.4325133,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"bounds":{"left":0.44115692,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"bounds":{"left":0.44980052,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"bounds":{"left":0.46077126,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"bounds":{"left":0.47174203,"top":0.09896249,"width":0.024268618,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"bounds":{"left":0.49833778,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"bounds":{"left":0.5093085,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7237367,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"21","depth":4,"bounds":{"left":0.6868351,"top":0.123703115,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.6984708,"top":0.123703115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"18","depth":4,"bounds":{"left":0.7077792,"top":0.123703115,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"}]...
|
6151574919104986669
|
5771048317937760189
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20915-fix-missing-head Project: faVsco.js, menu
JY-20915-fix-missing-header-text-relay, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
42
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models\Crm;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Jiminny\Component\Eloquent\Builder;
use Jiminny\Models\Ai\CrmTemplateField;
use Jiminny\Models\Model;
use Jiminny\Models\Playbook;
use Jiminny\Services\Crm\CrmObjects\FieldReadonlyConstants;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
/**
* Jiminny\Models\Crm\Field
*
* @property int $id
* @property mixed|null $uuid
* @property int $crm_configuration_id
* @property string $crm_provider_id
* @property string $label
* @property string|null $description
* @property string $type
* @property int|null $length
* @property string|null $default_value
* @property string $object_type
* @property bool $is_selectable
* @property bool $is_mandatory
* @property bool $is_filterable
* @property bool $is_indexable
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Jiminny\Models\Crm\Configuration $configuration
* @property-read \Jiminny\Models\Crm\Configuration $crm
* @property-read Collection<int, \Jiminny\Models\Crm\FieldData> $data
* @property-read int|null $data_count
* @property-read Collection<int, \Jiminny\Models\Crm\LayoutEntity> $entities
* @property-read int|null $entities_count
* @property-read string $id_string
* @property-read Collection<int, \Jiminny\Models\Crm\FieldValue> $values
* @property-read int|null $values_count
*
* @method static Builder|Field chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\Crm\FieldFactory factory(...$parameters)
* @method static Builder|Field idOrUuId($idOrUuid, bool $first = true)
* @method static Builder|Field indexable()
* @method static Builder|Field newModelQuery()
* @method static Builder|Field newQuery()
* @method static Builder|Field query()
* @method static Builder|Field tasks()
* @method static Builder|Field uuid(string $uuid, bool $first = true)
* @method static Builder|Field whereCreatedAt($value)
* @method static Builder|Field whereCrmConfigurationId($value)
* @method static Builder|Field whereCrmProviderId($value)
* @method static Builder|Field whereDefaultValue($value)
* @method static Builder|Field whereDescription($value)
* @method static Builder|Field whereId($value)
* @method static Builder|Field whereIsFilterable($value)
* @method static Builder|Field whereIsIndexable($value)
* @method static Builder|Field whereIsMandatory($value)
* @method static Builder|Field whereIsSelectable($value)
* @method static Builder|Field whereLabel($value)
* @method static Builder|Field whereLength($value)
* @method static Builder|Field whereObjectType($value)
* @method static Builder|Field whereType($value)
* @method static Builder|Field whereUpdatedAt($value)
* @method static Builder|Field whereUuid($value)
*
* @mixin \Eloquent
*/
class Field extends Model
{
use HasFactory;
use RequiresUUID;
use Enums;
public const int NAME_MAX_LENGTH = 128;
public const int LABEL_MAX_LENGTH = 255;
public const int DESCRIPTION_MAX_LENGTH = 191;
public const string TYPE_MULTIPICKLIST = 'multi-picklist';
// Not yet supported
public const string TYPE_PERCENT = 'percent';
public const string TYPE_PICKLIST = 'picklist';
public const string TYPE_NUMBER = 'number';
public const string TYPE_CURRENCY = 'currency';
public const string TYPE_BOOLEAN = 'boolean';
public const string TYPE_TEXT = 'text';
public const string TYPE_TEXTAREA = 'textarea';
public const string TYPE_EMAIL = 'email';
public const string TYPE_PHONE = 'phone';
public const string TYPE_URL = 'url';
public const string TYPE_DATE = 'date';
public const string TYPE_TIME = 'time';
public const string TYPE_DATETIME = 'datetime';
public const string TYPE_UNSUPPORTED = 'unsupported';
public const string OBJECT_LEAD = 'lead';
public const string OBJECT_ACCOUNT = 'account';
public const string OBJECT_CONTACT = 'contact';
public const string OBJECT_OPPORTUNITY = 'opportunity';
public const string OBJECT_TASK = 'task';
public const string OBJECT_EVENT = 'event';
public const string OBJECT_CALL = 'call';
public const string OBJECT_MEETING = 'meeting';
public const array BUSINESS_TYPE_FIELDS = [
Configuration::PROVIDER_SALESFORCE => 'Type',
Configuration::PROVIDER_HUBSPOT => 'dealtype',
];
public const array PIPELINE_TYPE_FIELDS = [
Configuration::PROVIDER_HUBSPOT => 'pipeline',
];
public const array STAGE_TYPE_FIELDS = [
Configuration::PROVIDER_SALESFORCE => 'StageName',
Configuration::PROVIDER_HUBSPOT => 'dealstage',
Configuration::PROVIDER_CLOSE => 'status_id',
Configuration::PROVIDER_BULLHORN => 'status',
Configuration::PROVIDER_PIPEDRIVE => 'stage_id',
Configuration::PROVIDER_COPPER => 'pipeline_stage_id',
];
public static $enumTypes = [
self::TYPE_PICKLIST,
self::TYPE_NUMBER,
self::TYPE_CURRENCY,
self::TYPE_BOOLEAN,
self::TYPE_TEXT,
self::TYPE_TEXTAREA,
self::TYPE_EMAIL,
self::TYPE_PHONE,
self::TYPE_URL,
self::TYPE_DATE,
self::TYPE_TIME,
self::TYPE_DATETIME,
self::TYPE_UNSUPPORTED,
];
public static $enumObjectTypes = [
self::OBJECT_LEAD,
self::OBJECT_ACCOUNT,
self::OBJECT_CONTACT,
self::OBJECT_OPPORTUNITY,
self::OBJECT_TASK,
self::OBJECT_EVENT,
];
protected $table = 'crm_fields';
protected $fillable = [
'crm_configuration_id',
'crm_provider_id',
'object_type',
'type',
'label',
'description',
'is_selectable',
'is_mandatory',
'length',
'default_value',
'is_indexable',
'is_filterable',
'is_readonly',
];
protected $appends = [
'id_string',
];
protected $hidden = [
'uuid',
'id',
'crm_configuration_id',
];
protected function casts(): array
{
return [
'is_selectable' => 'boolean',
'is_mandatory' => 'boolean',
'is_indexable' => 'boolean',
'is_filterable' => 'boolean',
];
}
public function configuration(): BelongsTo
{
return $this->belongsTo(Configuration::class, 'crm_configuration_id');
}
public function entities(): HasMany
{
return $this->hasMany(LayoutEntity::class, 'crm_field_id');
}
public function getEntities(): Collection
{
/** @var Collection<LayoutEntity> $entities */
$entities = $this->getAttribute('entities');
return $entities;
}
public function values(): HasMany
{
return $this->hasMany(FieldValue::class, 'crm_field_id')->orderBy('sequence');
}
public function getLabel(): string
{
return $this->getAttribute('label');
}
public function getType(): string
{
return $this->getAttribute('type');
}
public function getObjectType(): string
{
/** @var string */
return $this->getAttribute('object_type');
}
public function getCrmProviderId(): string
{
/** @var string */
return $this->getAttribute('crm_provider_id');
}
public function getValues(): Collection
{
return $this->getAttribute('values');
}
public function isIndexable(): bool
{
return $this->getAttribute('is_indexable');
}
public function isFilterable(): bool
{
return $this->getAttribute('is_filterable');
}
public function getId(): int
{
/** @var int */
return $this->getAttribute('id');
}
public function hasDescription(): bool
{
return $this->getAttribute('description') !== null;
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function data()
{
return $this->hasMany(FieldData::class, 'crm_field_id');
}
public function crm(): BelongsTo
{
return $this->belongsTo(Configuration::class, 'crm_configuration_id');
}
#[Scope]
protected function indexable($query)
{
return $query->where('is_indexable', 1);
}
#[Scope]
protected function tasks($query)
{
return $query->where('object_type', self::OBJECT_TASK);
}
public function isBusinessType(): bool
{
return in_array($this->getCrmProviderId(), self::BUSINESS_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function isStageField(): bool
{
return in_array($this->getCrmProviderId(), self::STAGE_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function isPipelineField(): bool
{
return in_array($this->getCrmProviderId(), self::PIPELINE_TYPE_FIELDS)
&& $this->getObjectType() === self::OBJECT_OPPORTUNITY;
}
public function getUuid(): string
{
return $this->getAttribute('id_string');
}
public function getCrmConfiguration(): Configuration
{
return $this->getAttribute('crm');
}
public function getCrmConfigurationId(): int
{
return $this->getAttribute('crm_configuration_id');
}
/**
* Currently implemented only for Opportunity fields
*/
public function isReadOnly(): bool
{
// The CRM Field metadata should always be first to be taken into consideration.
if ($this->getIsReadonly()) {
return true;
}
if ($this->getObjectType() !== self::OBJECT_OPPORTUNITY) {
return false;
}
if ($this->isPipelineField()) {
return true;
}
if ($this->getType() === Field::TYPE_UNSUPPORTED) {
return true;
}
if ($this->getCrmConfiguration()->getProviderName() === Configuration::PROVIDER_INTEGRATION_APP) {
$fieldDefinitions = new CrmFieldDefinitionsManager();
return $fieldDefinitions->isReadOnly($this->getCrmProviderId(), self::OBJECT_OPPORTUNITY);
}
return false;
}
public function isPicklist(): bool
{
return in_array($this->getType(), [self::TYPE_PICKLIST, self::TYPE_MULTIPICKLIST]);
}
public function getLength(): ?int
{
return $this->getAttribute('length');
}
public function getDefaultValue(): ?string
{
return $this->getAttribute('default_value');
}
public function setIsReadonly(int $isReadonly): void
{
$this->setAttribute('is_readonly', $isReadonly);
}
public function getIsReadonly(): bool
{
return $this->getAttribute('is_readonly') !== FieldReadonlyConstants::FIELD_IS_UPDATABLE;
}
public function getEntityName(): string
{
return ucfirst($this->getObjectType()) . '.' . $this->getCrmProviderId();
}
public function crmTemplateFields(): HasMany
{
return $this->hasMany(CrmTemplateField::class, 'crm_field_id');
}
public function playbooks(): HasMany
{
return $this->hasMany(Playbook::class, 'activity_field_id');
}
public function getPlaybooks(): Collection
{
return $this->getAttribute('playbooks');
}
}
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
21
1
18...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79470
|
2787
|
41
|
2026-05-28T06:30:59.617214+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949859617_m2.jpg...
|
Firefox
|
Jiminny — Work
|
1
|
app.dev.jiminny.com/playback/f43cf158-e60d-46e5-92 app.dev.jiminny.com/playback/f43cf158-e60d-46e5-92f8-c4e0594a3219...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 5 Q2 - Platform Team - Scrum Board Platform Sprint 5 Q2 - Platform Team - Scrum Board - Jira
[JY-20915] Add environment-specific email domains for text relay to prevent duplicate processing - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
BE upgrade libraries
[JY-20613] Allow owner's role to be selected when setting up a trial - Jira
[JY-20613] Allow owner's role to be selected when setting up a trial - Jira
Text relay
TypeError: Jiminny\Services\Mail\TextRelayService::setHistoryPoint(): Argument #2 ($historyPoint) must be of type int, string given, called in /home/jiminny/app/Services/Mail/TextRelayService.php on line 118 — jiminny — app
TypeError: Jiminny\Services\Mail\TextRelayService::setHistoryPoint(): Argument #2 ($historyPoint) must be of type int, string given, called in /home/jiminny/app/Services/Mail/TextRelayService.php on line 118 — jiminny — app
CloudWatch | us-east-2
CloudWatch | us-east-2
JY-20915 fix strict casting by LakyLak · Pull Request #12134 · jiminny/app
JY-20915 fix strict casting by LakyLak · Pull Request #12134 · jiminny/app
JY-20963 fix deleted object import by LakyLak · Pull Request #12121 · jiminny/app
JY-20963 fix deleted object import by LakyLak · Pull Request #12121 · jiminny/app
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
Lukas Kovalik - Time Off
Lukas Kovalik - Time Off
Jiminny
Jiminny
Login | Salesforce
Login | Salesforce
Jiminny\Exceptions\EmailActivityImportException: [Email Import] Failed for InboxEmail ID: 125695762: Error: Request failed — jiminny — app
Jiminny\Exceptions\EmailActivityImportException: [Email Import] Failed for InboxEmail ID: 125695762: Error: Request failed — jiminny — app
Invitation: All Hands - Product focus @ Tue Jun 2, 2026 11:30am - 12:30pm (GMT+3) (Lukas Kovalik) - [EMAIL] - Jiminny Mail
Invitation: All Hands - Product focus @ Tue Jun 2, 2026 11:30am - 12:30pm (GMT+3) (Lukas Kovalik) - [EMAIL] - Jiminny Mail
[JY-20979] Resolve PHP 8.5.5 deprications - Jira
[JY-20979] Resolve PHP 8.5.5 deprications - Jira
Jiminny
Jiminny
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Lukas Kovalik
New TITLE
Adelina Petrova at Robinson Crusoe Cruises Limited
Adelina Petrova at Robinson Crusoe Cruises Limited
|
Contract Sent
|
€455,554
|
90%
Meeting
|
13 Mar, 2:00 PM
CRM
Share
common.ai-icon-alt Ask me anything about this call...
Ask me anything about this call...
Flashback
Flashback
Transcript
Transcript
Themes
Themes
Statistics
Statistics
Questions
Questions
No transcript
This might be due to call being too short
Play Video
Play Video
1x
00:00
/ 01:44
Lukas Kovalik
Coaching
Coaching
Sidekick Notes
Sidekick Notes
Comments
Comments
Framework
Framework
Focus
Focus
Lukas Kovalik
Write Comment
Be first to comment and help your team...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 5 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0018284575,"top":0.0518755,"width":0.038065158,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"[JY-20915] Add environment-specific email domains for text relay to prevent duplicate processing - Jira","depth":4,"bounds":{"left":0.039893616,"top":0.0518755,"width":0.037898935,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.09497207,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.10614525,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"BE upgrade libraries","depth":4,"bounds":{"left":0.0028257978,"top":0.13288109,"width":0.03939495,"height":0.01915403},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"[JY-20613] Allow owner's role to be selected when setting up a trial - Jira","depth":4,"bounds":{"left":0.0,"top":0.15203512,"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-20613] Allow owner's role to be selected when setting up a trial - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.1632083,"width":0.12799202,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Text relay","depth":4,"bounds":{"left":0.0028257978,"top":0.18994413,"width":0.020279255,"height":0.01915403},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXRadioButton","text":"TypeError: Jiminny\\Services\\Mail\\TextRelayService::setHistoryPoint(): Argument #2 ($historyPoint) must be of type int, string given, called in /home/jiminny/app/Services/Mail/TextRelayService.php on line 118 — jiminny — app","depth":4,"bounds":{"left":0.0028257978,"top":0.21348763,"width":0.07679521,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"TypeError: Jiminny\\Services\\Mail\\TextRelayService::setHistoryPoint(): Argument #2 ($historyPoint) must be of type int, string given, called in /home/jiminny/app/Services/Mail/TextRelayService.php on line 118 — jiminny — app","depth":5,"bounds":{"left":0.015957447,"top":0.22466081,"width":0.38879654,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0028257978,"top":0.2462091,"width":0.07679521,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015957447,"top":0.25738227,"width":0.04138963,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20915 fix strict casting by LakyLak · Pull Request #12134 · jiminny/app","depth":4,"bounds":{"left":0.0028257978,"top":0.27893057,"width":0.07679521,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20915 fix strict casting by LakyLak · Pull Request #12134 · jiminny/app","depth":5,"bounds":{"left":0.015957447,"top":0.29010376,"width":0.1278258,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20963 fix deleted object import by LakyLak · Pull Request #12121 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.31165203,"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-20963 fix deleted object import by LakyLak · Pull Request #12121 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.32282522,"width":0.14245346,"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.0,"top":0.3443735,"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.013297873,"top":0.35554668,"width":0.4644282,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Lukas Kovalik - Time Off","depth":4,"bounds":{"left":0.0,"top":0.37709498,"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":"Lukas Kovalik - Time Off","depth":5,"bounds":{"left":0.013297873,"top":0.38826814,"width":0.042220745,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.40981644,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.013297873,"top":0.42098963,"width":0.013131649,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Login | Salesforce","depth":4,"bounds":{"left":0.0,"top":0.4425379,"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":"Login | Salesforce","depth":5,"bounds":{"left":0.013297873,"top":0.4537111,"width":0.030917553,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny\\Exceptions\\EmailActivityImportException: [Email Import] Failed for InboxEmail ID: 125695762: Error: Request failed — jiminny — app","depth":4,"bounds":{"left":0.0,"top":0.47525936,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny\\Exceptions\\EmailActivityImportException: [Email Import] Failed for InboxEmail ID: 125695762: Error: Request failed — jiminny — app","depth":5,"bounds":{"left":0.013297873,"top":0.48643255,"width":0.24301861,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Invitation: All Hands - Product focus @ Tue Jun 2, 2026 11:30am - 12:30pm (GMT+3) (Lukas Kovalik) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.0,"top":0.5079808,"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":"Invitation: All Hands - Product focus @ Tue Jun 2, 2026 11:30am - 12:30pm (GMT+3) (Lukas Kovalik) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.013297873,"top":0.519154,"width":0.24966756,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20979] Resolve PHP 8.5.5 deprications - Jira","depth":4,"bounds":{"left":0.0,"top":0.54070234,"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-20979] Resolve PHP 8.5.5 deprications - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.5518755,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.5734238,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.013297873,"top":0.584597,"width":0.013131649,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.5806065,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.0028257978,"top":0.6077414,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0028257978,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.013796543,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.024933511,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.036070477,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.04720745,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lukas Kovalik","depth":10,"bounds":{"left":0.107546546,"top":0.06464485,"width":0.013131649,"height":0.023942538},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"New TITLE","depth":9,"bounds":{"left":0.11951463,"top":0.06703911,"width":0.029587766,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Adelina Petrova at Robinson Crusoe Cruises Limited","depth":8,"bounds":{"left":0.107546546,"top":0.090183556,"width":0.12400266,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Adelina Petrova at Robinson Crusoe Cruises Limited","depth":10,"bounds":{"left":0.1143617,"top":0.090183556,"width":0.11020612,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"|","depth":9,"bounds":{"left":0.23387633,"top":0.101356745,"width":0.0013297872,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Contract Sent","depth":9,"bounds":{"left":0.23620346,"top":0.090183556,"width":0.029421542,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"|","depth":9,"bounds":{"left":0.2679521,"top":0.101356745,"width":0.0013297872,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"€455,554","depth":9,"bounds":{"left":0.27027926,"top":0.090183556,"width":0.020279255,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"|","depth":9,"bounds":{"left":0.29288563,"top":0.101356745,"width":0.0013297872,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"90%","depth":9,"bounds":{"left":0.29521278,"top":0.090183556,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Meeting","depth":9,"bounds":{"left":0.107546546,"top":0.10694334,"width":0.017287234,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"|","depth":9,"bounds":{"left":0.1271609,"top":0.11811652,"width":0.0014960107,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13 Mar, 2:00 PM","depth":9,"bounds":{"left":0.13730054,"top":0.10694334,"width":0.034242023,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CRM","depth":8,"bounds":{"left":0.45644948,"top":0.07821229,"width":0.028756648,"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":"Share","depth":8,"bounds":{"left":0.4878657,"top":0.07821229,"width":0.037732713,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"common.ai-icon-alt Ask me anything about this call...","depth":6,"bounds":{"left":0.107546546,"top":0.14285715,"width":0.24235372,"height":0.03671189},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask me anything about this call...","depth":7,"bounds":{"left":0.12516622,"top":0.15442938,"width":0.0653258,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Flashback","depth":8,"bounds":{"left":0.107546546,"top":0.18914606,"width":0.03939495,"height":0.03830806},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Flashback","depth":10,"bounds":{"left":0.121509306,"top":0.20151636,"width":0.02044548,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Transcript","depth":8,"bounds":{"left":0.14694148,"top":0.18914606,"width":0.040392287,"height":0.03830806},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Transcript","depth":10,"bounds":{"left":0.16090426,"top":0.20151636,"width":0.02144282,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Themes","depth":8,"bounds":{"left":0.18733378,"top":0.18914606,"width":0.03507314,"height":0.03830806},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Themes","depth":10,"bounds":{"left":0.20129654,"top":0.20151636,"width":0.016123671,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Statistics","depth":8,"bounds":{"left":0.22240691,"top":0.18914606,"width":0.03756649,"height":0.03830806},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Statistics","depth":10,"bounds":{"left":0.23636968,"top":0.20151636,"width":0.01861702,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Questions","depth":8,"bounds":{"left":0.2599734,"top":0.18914606,"width":0.039727394,"height":0.03830806},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Questions","depth":10,"bounds":{"left":0.27393618,"top":0.20151636,"width":0.020777926,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No transcript","depth":10,"bounds":{"left":0.21259974,"top":0.40542698,"width":0.032247342,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"This might be due to call being too short","depth":10,"bounds":{"left":0.18766622,"top":0.42897046,"width":0.08211436,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Play Video","depth":10,"bounds":{"left":0.35987368,"top":0.15083799,"width":0.019946808,"height":0.023942538},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Play Video","depth":12,"bounds":{"left":0.3698471,"top":0.16520351,"width":0.017121011,"height":0.04349561},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1x","depth":14,"bounds":{"left":0.3648604,"top":0.50239426,"width":0.004488032,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"00:00","depth":11,"bounds":{"left":0.4635971,"top":0.5371109,"width":0.012134309,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/ 01:44","depth":12,"bounds":{"left":0.47573137,"top":0.5371109,"width":0.015957447,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":16,"bounds":{"left":0.36186835,"top":0.5606544,"width":0.011136968,"height":0.019952115},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Coaching","depth":7,"bounds":{"left":0.3565492,"top":0.62968874,"width":0.038231384,"height":0.03830806},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Coaching","depth":9,"bounds":{"left":0.37051198,"top":0.6420591,"width":0.019281914,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Sidekick Notes","depth":7,"bounds":{"left":0.39478058,"top":0.62968874,"width":0.04920213,"height":0.03830806},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sidekick Notes","depth":9,"bounds":{"left":0.40874335,"top":0.6420591,"width":0.03025266,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Comments","depth":9,"bounds":{"left":0.3565492,"top":0.6679968,"width":0.032413565,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Comments","depth":11,"bounds":{"left":0.3615359,"top":0.6771748,"width":0.02244016,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Framework","depth":9,"bounds":{"left":0.38896278,"top":0.6679968,"width":0.03357713,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Framework","depth":11,"bounds":{"left":0.39394948,"top":0.6771748,"width":0.023603724,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Focus","depth":9,"bounds":{"left":0.4225399,"top":0.6679968,"width":0.021941489,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Focus","depth":11,"bounds":{"left":0.4275266,"top":0.6771748,"width":0.011968086,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":11,"bounds":{"left":0.36186835,"top":0.7126895,"width":0.01662234,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Write Comment","depth":10,"bounds":{"left":0.3771609,"top":0.7126895,"width":0.21625665,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Be first to comment and help your team","depth":10,"bounds":{"left":0.43068483,"top":0.7893057,"width":0.104222074,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-546757737767840151
|
-2880229459006209521
|
visual_change
|
accessibility
|
NULL
|
Platform Sprint 5 Q2 - Platform Team - Scrum Board Platform Sprint 5 Q2 - Platform Team - Scrum Board - Jira
[JY-20915] Add environment-specific email domains for text relay to prevent duplicate processing - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
BE upgrade libraries
[JY-20613] Allow owner's role to be selected when setting up a trial - Jira
[JY-20613] Allow owner's role to be selected when setting up a trial - Jira
Text relay
TypeError: Jiminny\Services\Mail\TextRelayService::setHistoryPoint(): Argument #2 ($historyPoint) must be of type int, string given, called in /home/jiminny/app/Services/Mail/TextRelayService.php on line 118 — jiminny — app
TypeError: Jiminny\Services\Mail\TextRelayService::setHistoryPoint(): Argument #2 ($historyPoint) must be of type int, string given, called in /home/jiminny/app/Services/Mail/TextRelayService.php on line 118 — jiminny — app
CloudWatch | us-east-2
CloudWatch | us-east-2
JY-20915 fix strict casting by LakyLak · Pull Request #12134 · jiminny/app
JY-20915 fix strict casting by LakyLak · Pull Request #12134 · jiminny/app
JY-20963 fix deleted object import by LakyLak · Pull Request #12121 · jiminny/app
JY-20963 fix deleted object import by LakyLak · Pull Request #12121 · jiminny/app
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
Lukas Kovalik - Time Off
Lukas Kovalik - Time Off
Jiminny
Jiminny
Login | Salesforce
Login | Salesforce
Jiminny\Exceptions\EmailActivityImportException: [Email Import] Failed for InboxEmail ID: 125695762: Error: Request failed — jiminny — app
Jiminny\Exceptions\EmailActivityImportException: [Email Import] Failed for InboxEmail ID: 125695762: Error: Request failed — jiminny — app
Invitation: All Hands - Product focus @ Tue Jun 2, 2026 11:30am - 12:30pm (GMT+3) (Lukas Kovalik) - [EMAIL] - Jiminny Mail
Invitation: All Hands - Product focus @ Tue Jun 2, 2026 11:30am - 12:30pm (GMT+3) (Lukas Kovalik) - [EMAIL] - Jiminny Mail
[JY-20979] Resolve PHP 8.5.5 deprications - Jira
[JY-20979] Resolve PHP 8.5.5 deprications - Jira
Jiminny
Jiminny
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Lukas Kovalik
New TITLE
Adelina Petrova at Robinson Crusoe Cruises Limited
Adelina Petrova at Robinson Crusoe Cruises Limited
|
Contract Sent
|
€455,554
|
90%
Meeting
|
13 Mar, 2:00 PM
CRM
Share
common.ai-icon-alt Ask me anything about this call...
Ask me anything about this call...
Flashback
Flashback
Transcript
Transcript
Themes
Themes
Statistics
Statistics
Questions
Questions
No transcript
This might be due to call being too short
Play Video
Play Video
1x
00:00
/ 01:44
Lukas Kovalik
Coaching
Coaching
Sidekick Notes
Sidekick Notes
Comments
Comments
Framework
Framework
Focus
Focus
Lukas Kovalik
Write Comment
Be first to comment and help your team...
|
79469
|
NULL
|
NULL
|
NULL
|
|
79469
|
2787
|
40
|
2026-05-28T06:30:57.813899+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949857813_m2.jpg...
|
CleanShot X
|
CleanShot
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Plosines - liminnwhorBE upgrade libraries(JY-20613 Plosines - liminnwhorBE upgrade libraries(JY-20613) Allow owner's role to tText relayTypeError: Jiminry\Services|MaCloudWatch | us-east-zJY-20915 fx strict casting by LaJY-20963 fix deleted object impolSevenShores\Hubspot|ExceptionstLukas Kovalik - Time Of8 JiminnyLogin | SalesforceJiminny|Exceptions|EmailActivitytrM Invitation: All Hands - Product focY-20979) Rotolve PHP 8.5.5 del8 JiminnyhresetsGradientsShado210%• Adelina Petrova at Robinson Crusoe Cruises Limited C Contract Sent €455.554 90.snowlessUAtto-weirneCarnerCURRENT STAGEContract SentSU8IECTSTART DATE TIMESNODAT TIourcoMECall OutcomiTGCATIONSUBJECTNew Titl fCAIIGIUUAOYIteetine1OGTO CMECEO2CEDrag Me*V CRMSave as.00:00/01:44CaortntoeFocuse) Re first to comment and helpAdelina Patrow?AetivinY TYpEMeetingOPPORTUNITYNew Deal for Manual Sync ChangCURRENT STAG!Contract SentTYPPSUBJECHSIAkTORIZTIMEEND DATE TIMEREMINDER DATE/TIMEtcoMSCall OutcomelLOCATIONISUBJECTNew TITLECARI GLILALAAONtestinyLOG TO SALESFORC!Next Steps-Los to Salesforce5002002002002002a0(200See(200280200403580500500InspectorFite URLSGETGETGE,GEGETGETGETGETHEADHEALPOSTGEYGE,GETGETGE,GETGETGE)GE,GETPOSTGETGETE ConsoloDebucadapp.dev.minny.comapp.dev.jminny.comapp.dev.sminny.comapp.dev.jiminny.comapp.dev.jminny.comapp.dev.minny.comapp.dev.jminny.comwapp.dev.sminny.comapp.dev.jminny.comaoo.dev smintyapp.dev.jminny.comapp.dev.minny.com#[EMAIL] usarr lotoo.dev.sminny.comapp.dev.jminny.comapp.dev.jminny.comtind.userpilok.kapp.dev.jminny.comttwoo.dev.smtnty.coapp.dev.jminny.comapp.dev.minny.comapp.dev.jminny.comwapp.dev.sminny.conapp.dev.jminny.comapp.dev.iminny.comapp.dev.gminny.comapi-iam.intercom.knop.dey mincy.cor#app.dev.jminey.comehon.deumnou.co.app.dev.minny.comTOOУLYThu 28 May 9:30:57T+ NetworkStyle EditoPertormancdEta MemonStornadTh AccessibiityAnolication©69143c/158-e60d-4605-9218-04e0594a3219stug.coeettoieiwonttehorlieedena nebeltnhedoatesten KotehcusneornyerzlurecuttwonyarnlehdNX-34388400ap0. /1:2 (xhe)AReMCRLNOrLARAK-OnR.cAnhr04.2210/ot/:.wo.oos.ne.0c5ewhttRwherm%uscpportunity?contactid=0032g00000XXBFIAAtasks?prospectid:0032000000XX8FIAA1&ob/ectTypexcontactar 4 vuex.esm-bundler-Daful+6а36838-86a3-43e9-9816-b6a65ca3/11c.m3u8aoton.cort.roth.bbweroctheththr/te.mkmAIARANA ARAN INNORORtE KeOGERSintE mOndVioeossSoinlessyue*• X418 21415.02 kR42B 21411 B 22028 2128 20A38122107kB221713 kB260816OB/1396 B 18:632Bo127MEo28RRNK15.92 kB8.81 kE2.61 kE231 B15.92 kl1.27 ME1.27 MB35 requests |GAR MRYARAMA tranatMto...
|
NULL
|
-498916420252837875
|
NULL
|
click
|
ocr
|
NULL
|
Plosines - liminnwhorBE upgrade libraries(JY-20613 Plosines - liminnwhorBE upgrade libraries(JY-20613) Allow owner's role to tText relayTypeError: Jiminry\Services|MaCloudWatch | us-east-zJY-20915 fx strict casting by LaJY-20963 fix deleted object impolSevenShores\Hubspot|ExceptionstLukas Kovalik - Time Of8 JiminnyLogin | SalesforceJiminny|Exceptions|EmailActivitytrM Invitation: All Hands - Product focY-20979) Rotolve PHP 8.5.5 del8 JiminnyhresetsGradientsShado210%• Adelina Petrova at Robinson Crusoe Cruises Limited C Contract Sent €455.554 90.snowlessUAtto-weirneCarnerCURRENT STAGEContract SentSU8IECTSTART DATE TIMESNODAT TIourcoMECall OutcomiTGCATIONSUBJECTNew Titl fCAIIGIUUAOYIteetine1OGTO CMECEO2CEDrag Me*V CRMSave as.00:00/01:44CaortntoeFocuse) Re first to comment and helpAdelina Patrow?AetivinY TYpEMeetingOPPORTUNITYNew Deal for Manual Sync ChangCURRENT STAG!Contract SentTYPPSUBJECHSIAkTORIZTIMEEND DATE TIMEREMINDER DATE/TIMEtcoMSCall OutcomelLOCATIONISUBJECTNew TITLECARI GLILALAAONtestinyLOG TO SALESFORC!Next Steps-Los to Salesforce5002002002002002a0(200See(200280200403580500500InspectorFite URLSGETGETGE,GEGETGETGETGETHEADHEALPOSTGEYGE,GETGETGE,GETGETGE)GE,GETPOSTGETGETE ConsoloDebucadapp.dev.minny.comapp.dev.jminny.comapp.dev.sminny.comapp.dev.jiminny.comapp.dev.jminny.comapp.dev.minny.comapp.dev.jminny.comwapp.dev.sminny.comapp.dev.jminny.comaoo.dev smintyapp.dev.jminny.comapp.dev.minny.com#[EMAIL] usarr lotoo.dev.sminny.comapp.dev.jminny.comapp.dev.jminny.comtind.userpilok.kapp.dev.jminny.comttwoo.dev.smtnty.coapp.dev.jminny.comapp.dev.minny.comapp.dev.jminny.comwapp.dev.sminny.conapp.dev.jminny.comapp.dev.iminny.comapp.dev.gminny.comapi-iam.intercom.knop.dey mincy.cor#app.dev.jminey.comehon.deumnou.co.app.dev.minny.comTOOУLYThu 28 May 9:30:57T+ NetworkStyle EditoPertormancdEta MemonStornadTh AccessibiityAnolication©69143c/158-e60d-4605-9218-04e0594a3219stug.coeettoieiwonttehorlieedena nebeltnhedoatesten KotehcusneornyerzlurecuttwonyarnlehdNX-34388400ap0. /1:2 (xhe)AReMCRLNOrLARAK-OnR.cAnhr04.2210/ot/:.wo.oos.ne.0c5ewhttRwherm%uscpportunity?contactid=0032g00000XXBFIAAtasks?prospectid:0032000000XX8FIAA1&ob/ectTypexcontactar 4 vuex.esm-bundler-Daful+6а36838-86a3-43e9-9816-b6a65ca3/11c.m3u8aoton.cort.roth.bbweroctheththr/te.mkmAIARANA ARAN INNORORtE KeOGERSintE mOndVioeossSoinlessyue*• X418 21415.02 kR42B 21411 B 22028 2128 20A38122107kB221713 kB260816OB/1396 B 18:632Bo127MEo28RRNK15.92 kB8.81 kE2.61 kE231 B15.92 kl1.27 ME1.27 MB35 requests |GAR MRYARAMA tranatMto...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
79468
|
2786
|
20
|
2026-05-28T06:30:57.713474+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779949857713_m1.jpg...
|
CleanShot X
|
CleanShot
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Presets...
None
Gradients
Wallpapers
Blurred
Plain Presets...
None
Gradients
Wallpapers
Blurred
Plain color
Padding
0
Inset
0
Auto-balance
Shadow
0
Corners
0
Alignment
Ratio
210%...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Presets...","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"None","depth":5,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Gradients","depth":5,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Wallpapers","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Blurred","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Plain color","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Padding","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"0","depth":2,"on_screen":true,"value":"0","role_description":"text field","is_enabled":true,"is_focused":false},{"role":"AXStaticText","text":"Inset","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"0","depth":2,"on_screen":true,"value":"0","role_description":"text field","is_enabled":true,"is_focused":false},{"role":"AXCheckBox","text":"Auto-balance","depth":2,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false},{"role":"AXStaticText","text":"Shadow","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"0","depth":2,"on_screen":true,"value":"0","role_description":"text field","is_enabled":true,"is_focused":false},{"role":"AXStaticText","text":"Corners","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"0","depth":2,"on_screen":true,"value":"0","role_description":"text field","is_enabled":true,"is_focused":false},{"role":"AXStaticText","text":"Alignment","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Ratio","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"210%","depth":1,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false}]...
|
1570808103314279303
|
6193159828948910416
|
click
|
accessibility
|
NULL
|
Presets...
None
Gradients
Wallpapers
Blurred
Plain Presets...
None
Gradients
Wallpapers
Blurred
Plain color
Padding
0
Inset
0
Auto-balance
Shadow
0
Corners
0
Alignment
Ratio
210%...
|
79464
|
NULL
|
NULL
|
NULL
|